home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 8
/
The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO
/
g_quake
/
3wave23.zip
/
CAPTURE.DIF
< prev
next >
Wrap
Text File
|
1996-10-14
|
110KB
|
3,990 lines
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/charset.txt src/charset.txt
--- v106qc/charset.txt Wed Dec 31 19:00:00 1969
+++ src/charset.txt Mon Oct 14 01:49:38 1996
@@ -0,0 +1,25 @@
+/*
+Earth Magic = ┼ß≥⌠Φ ═ßτΘπ
+Resistance = ╥σ≤Θ≤⌠ßεπσ
+Black Magic = ┬∞πßδ ═ßτΘπ
+Strength = ╙⌠≥σετ⌠Φ
+Hell Magic = ╚σ∞∞ ═ßτΘπ
+Haste = ╚ß≤⌠σ
+Elder Magic = ┼∞Σσ≥ ═ßτΘπ
+Regeneration = ╥στσεσ≥ß⌠Θ∩ε
+BLUE = ┬╠╒┼
+RED = ╥┼─
+YOU GOT THE ENEMY FLAG = ┘╧╒ ╟╧╘ ╘╚┼ ┼╬┼═┘ ╞╠┴╟
+RETURN TO BASE = ╥┼╘╒╥╬ ╘╧ ┬┴╙┼
+CAPTURE THE FLAG = ├┴╨╘╒╥┼ ╘╚┼ ╞╠┴╟
+captured = πß≡⌠⌡≥σΣ
+got = τ∩⌠
+lost = ∞∩≤⌠
+returned = ≥σ⌠⌡≥εσΣ
+
+ABCDEFGHIJKLMNOPQRSTUVWXYZ
+┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌
+
+abcdefghijklmnopqrstuvwxyz
+ßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙√
+*/
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/client.qc src/client.qc
--- v106qc/client.qc Sun Sep 29 23:29:00 1996
+++ src/client.qc Mon Oct 14 01:04:43 1996
@@ -6,9 +6,67 @@
void() player_stand1;
void (vector org) spawn_tfog;
void (vector org, entity death_owner) spawn_tdeath;
+string(string old) RandomLevel;
float modelindex_eyes, modelindex_player;
+void() MOTD =
+{
+ if (self.motd_count < 5) {
+ self.motd_time = time + 1;
+ self.motd_count = self.motd_count + 1;
+ if (teamplay & TEAM_CAPTURE_FLAG)
+ if (self.team == TEAM_COLOR1 + 1)
+ centerprint(self, "Welcome to Quake.ThreeWave.COM\nYour admin is Zoid.\n\n├┴╨╘╒╥┼ ╘╚┼ ╞╠┴╟!\n\nYou are ╥┼─ team\n"); //red
+ else
+ centerprint(self, "Welcome to Quake.ThreeWave.COM\nYour admin is Zoid.\n\n├┴╨╘╒╥┼ ╘╚┼ ╞╠┴╟!\n\nYou are ┬╠╒┼ team"); //blue
+ else if (teamplay)
+ centerprint(self, "Welcome to Quake.ThreeWave.COM\nYour admin is Zoid.\n\nTEAMPLAY IS ACTIVE");
+ else
+ centerprint(self, "Welcome to Quake.ThreeWave.COM\nYour admin is Zoid.");
+ return;
+ } else {
+ sprint(self, "Info: http://quake.threewave.com/\n");
+ if (teamplay)
+ sprint(self, "Impulse 25 for Team Settings\n");
+ if (teamplay & TEAM_CAPTURE_FLAG)
+ sprint(self, "You are playing ├┴╨╘╒╥┼ ╘╚┼ ╞╠┴╟!\n"); // CAPTURE THE FLAG
+ }
+ self.motd_time = 0;
+};
+
+// ZOID: with several effects doing the dimlight thing, they just can't
+// turn it off. Do not set self.effects with EF_DIMLIGHT directly. This
+// will automatically do it when CheckPowerups is called
+// EF_DIMLIGHT is used;
+// 1. Invincible (Pentagram)
+// 2. Super Damage (Quad Power)
+// 3. Having Flag in Capture
+// 4. On fire (flamethrower)
+// self is player
+void () CheckDimLight = {
+ local float flag;
+
+ flag = 0;
+ // invincable
+ if (self.invincible_finished > time)
+ flag = 1;
+ // quad
+ if (self.super_damage_finished > time)
+ flag = 1;
+ // flag
+ if (self.player_flag & ITEM_ENEMY_FLAG)
+ flag = 1;
+ // On fire
+ if (self.onfire)
+ flag = 1;
+
+ if (flag)
+ self.effects = self.effects | EF_DIMLIGHT;
+ else
+ self.effects = self.effects - (self.effects & EF_DIMLIGHT);
+};
+
/*
=============================================================================
@@ -59,11 +117,14 @@
parm7 = self.ammo_cells;
parm8 = self.weapon;
parm9 = self.armortype * 100;
+// *TEAMPLAY*
+ parm10 = self.lastteam; // Save the current team of the player
+ parm16 = self.player_flag;
};
void() SetNewParms =
{
- parm1 = IT_SHOTGUN | IT_AXE;
+ parm1 = IT_SHOTGUN | IT_AXE | IT_HOOK;
parm2 = 100;
parm3 = 0;
parm4 = 25;
@@ -72,10 +133,21 @@
parm7 = 0;
parm8 = 1;
parm9 = 0;
+// *TEAMPLAY*
+ parm10 = -1; // Reset
+ parm16 = 0;
};
void() DecodeLevelParms =
{
+ self.player_flag = parm16;
+ self.player_flag = self.player_flag - (self.player_flag & ITEM_RUNE_MASK);
+ self.player_flag = self.player_flag - (self.player_flag & ITEM_ENEMY_FLAG);
+ if (teamplay == 0)
+ self.skin = (self.player_flag & 65280)/256;
+ else
+ self.skin = 0; // default to the Quake dude
+
if (serverflags)
{
if (world.model == "maps/start.bsp")
@@ -91,6 +163,9 @@
self.ammo_cells = parm7;
self.weapon = parm8;
self.armortype = parm9 * 0.01;
+// *TEAMPLAY*
+ if(TeamColorIsLegal(parm10 - 1))
+ self.lastteam = parm10;
};
/*
@@ -258,7 +333,7 @@
// enforce a wait time before allowing changelevel
if (deathmatch)
- intermission_exittime = time + 5;
+ intermission_exittime = time + 8;
else
intermission_exittime = time + 2;
@@ -294,6 +369,9 @@
if (other.classname != "player")
return;
+ if ((cvar("noexit") == 1) && (teamplay & TEAM_CAPTURE_FLAG))
+ return;
+
if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start")))
{
T_Damage (other, self, self, 50000);
@@ -306,6 +384,10 @@
bprint (" exited the level\n");
}
+// ZOID - go to next level randomly
+ if (deathmatch)
+ nextmap = RandomLevel(mapname);
+ else
nextmap = self.map;
SUB_UseTargets ();
@@ -384,11 +466,25 @@
*/
void() ClientKill =
{
+ if (self.suicide_count > 3) {
+ sprint(self, "You have suicided too much already.\n");
+ return;
+ }
bprint (self.netname);
bprint (" suicides\n");
+ DropRune();
+ TeamCaptureDropFlag();
set_suicide_frame ();
self.modelindex = modelindex_player;
self.frags = self.frags - 2; // extra penalty
+ self.suicide_count = self.suicide_count + 1;
+ respawn ();
+};
+
+void() SilentKill =
+{
+ set_suicide_frame ();
+ self.modelindex = modelindex_player;
respawn ();
};
@@ -407,8 +503,6 @@
entity() SelectSpawnPoint =
{
local entity spot;
- local entity thing;
- local float pcount;
// testinfo_player_start is only found in regioned levels
spot = find (world, classname, "testplayerstart");
@@ -426,29 +520,16 @@
}
else if (deathmatch)
{
- spot = lastspawn;
- while (1)
- {
- spot = find(spot, classname, "info_player_deathmatch");
+ if (!self.killed) {
+ spot = TeamCaptureSpawn();
if (spot != world)
- {
- if (spot == lastspawn)
- return lastspawn;
- pcount = 0;
- thing = findradius(spot.origin, 32);
- while(thing)
- {
- if (thing.classname == "player")
- pcount = pcount + 1;
- thing = thing.chain;
- }
- if (pcount == 0)
- {
- lastspawn = spot;
return spot;
}
- }
- }
+ lastspawn = find(lastspawn, classname, "info_player_deathmatch");
+ if (lastspawn == world)
+ lastspawn = find (lastspawn, classname, "info_player_deathmatch");
+ if (lastspawn != world)
+ return lastspawn;
}
if (serverflags)
@@ -481,6 +562,9 @@
local entity spot;
spot = SelectSpawnPoint ();
+//ZOID: Minimize chance of telefragging someone, from Johannes Plass
+//(plass@dipmza.physik.uni-mainz.de) ServerModules package
+ spot = TelefragSelectSpawnPoint(spot);
self.classname = "player";
self.health = 100;
@@ -498,6 +582,12 @@
self.invincible_finished = 0;
self.effects = 0;
self.invincible_time = 0;
+ self.staydeadtime = 0;
+ self.regen_time = 0;
+ self.rune_notice_time = 0;
+
+ // Flamethrower - just to be sure
+ self.onfire = FALSE;
DecodeLevelParms ();
@@ -537,6 +627,40 @@
}
spawn_tdeath (self.origin, self);
+
+// *********************************************************************
+// ** **
+// ** M U L T I S K I N 1.1 (start) **
+// ** **
+// ***********************************************************************
+
+ if (teamplay == 0) {
+ if (self.skin == 0) centerprint(self, "Mr. Quake himself!"); else
+ if (self.skin == 1) centerprint(self, "No time to play with yourself here!"); else
+ if (self.skin == 2) centerprint(self, "You're one pretty toad!"); else
+ if (self.skin == 3) centerprint(self, "Wow Stormtrooper, you're though!"); else
+ if (self.skin == 4) centerprint(self, "Hi Max, looking yellow/blue today!"); else
+ if (self.skin == 5) centerprint(self, "You are back!"); else
+ if (self.skin == 6) centerprint(self, "Judge Dredd! Let's restore some order!"); else
+ if (self.skin == 7) centerprint(self, "Camo! Can't see you, where are you!"); else
+ if (self.skin == 8) centerprint(self, "Okay Captain Picard, make it so!"); else
+ if (self.skin == 9) centerprint(self, "Whizz whizz.. Wizzard!"); else
+ if (self.skin == 10) centerprint(self,"I'm the Predator, you're the prey!"); else
+ if (self.skin == 11) centerprint(self,"Welcome Skeleton, looking good!"); else
+ if (self.skin == 12) centerprint(self,"Wan-Fu, whoever you are :)"); else
+ if (self.skin == 13) centerprint(self,"Oh no, it's Henry Rollins!"); else
+ if (self.skin == 14) centerprint(self,"Ooh no, it's She.. eh.. He-Man"); else
+ if (self.skin == 15) centerprint(self,"If it isn't Boba, go get Han Solo!"); else
+ if (self.skin == 16) centerprint(self,"It's SUPERMAN!"); else
+ if (self.skin == 17) centerprint(self,"Protect the innocent, uphold your law"); else
+ if (self.skin == 18) centerprint(self,"Why is that symbol on your suit?");
+ }
+
+// *************************************************************************
+// ** **
+// ** M U L T I S K I N 1.1 (end) **
+// ** **
+// *************************************************************************
};
@@ -565,6 +689,8 @@
};
+void() SpawnRunes;
+
/*
saved out by quaked in region mode
*/
@@ -577,6 +703,22 @@
*/
void() info_player_deathmatch =
{
+ local entity rspawn;
+
+ if (deathmatch) {
+ // spawn the runes
+ rspawn = spawn();
+ rspawn.nextthink = time + 0.1;
+ rspawn.think = SpawnRunes;
+ }
+};
+
+void() info_player_team1 =
+{
+};
+
+void() info_player_team2 =
+{
};
/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24)
@@ -634,16 +776,21 @@
}
else
{
+//ZOID: RandomLevel is called. Note that RandomLevel handles Capture
+//levels as well.
+ o = spawn();
+ o.map = RandomLevel(mapname);
+
// find a trigger changelevel
- o = find(world, classname, "trigger_changelevel");
+// o = find(world, classname, "trigger_changelevel");
// go back to start if no trigger_changelevel
- if (!o)
- {
- mapname = "start";
- o = spawn();
- o.map = mapname;
- }
+// if (!o)
+// {
+// mapname = "start";
+// o = spawn();
+// o.map = mapname;
+// }
}
nextmap = o.map;
@@ -654,6 +801,78 @@
o.think = execute_changelevel;
o.nextthink = time + 0.1;
}
+
+};
+
+// Return a new random level, that doesn't match old
+string(string old) RandomLevel =
+{
+local float r;
+
+ r = random();
+ if (teamplay & TEAM_CAPTURE_FLAG) {
+ // capture levels
+ if (old == "e1m1") return "e1m2";
+ if (old == "e1m2") return "e1m3";
+ if (old == "e1m3") return "e1m4";
+ if (old == "e1m4") return "e1m5";
+ if (old == "e1m5") return "e1m6";
+ if (old == "e1m6") return "e1m8";
+ if (old == "e1m8") return "e2m1";
+ if (old == "e2m1") return "e2m2";
+ if (old == "e2m2") return "e2m3";
+ if (old == "e2m3") return "e2m5";
+ if (old == "e2m5") return "e4m3";
+ return "e1m1";
+ }
+ if (r > 0.8) {
+ r = random() * 7;
+ if ((r >= 6) && (old != "e1m1")) return ("e1m1"); // e1m1: Slipgate Complex -- by John Romero
+ if ((r >= 5) && (old != "e1m2")) return ("e1m2"); // e1m2: Castle of the Damned -- by Tim Willits
+ if ((r >= 4) && (old != "e1m3")) return ("e1m3"); // e1m3: The Necropolis -- by Tim Willits
+ if ((r >= 3) && (old != "e1m4")) return ("e1m4"); // e1m4: The Grisly Grotto -- by Tim Willits
+ if ((r >= 2) && (old != "e1m5")) return ("e1m5"); // e1m5: Gloom Keep -- by Tim Willits
+ if ((r >= 1) && (old != "e1m6")) return ("e1m6"); // e1m6: The Door To Chthon -- by American McGee
+// e1m7: The House of Chthon -- removed because of lag problems
+ return ("e1m8"); // e1m8: Ziggurat Vertigo --by American McGee
+ } else if (r > 0.6) {
+ r = random() * 6;
+ if ((r >= 5) && (old != "e2m1")) return ("e2m1"); // e2m1: The Installation -- by John Romero
+ if ((r >= 4) && (old != "e2m2")) return ("e2m2"); // e2m2: Ogre Citadel -- by John Romero
+ if ((r >= 3) && (old != "e2m3")) return ("e2m3"); // e2m3: Crypt of Decay -- by John Romero
+ if ((r >= 2) && (old != "e2m4")) return ("e2m4"); // e2m4: The Ebon Fortress -- by John Romero
+ if ((r >= 1) && (old != "e2m5")) return ("e2m5"); // e2m5: The Wizard's Manse -- by John Romero
+// e2m6: The Dismal Oubliette -- removed because it sucks for dm
+ return ("e2m7"); // e2m7: Underearth --by Tim Willits
+ } else if (r > 0.4) {
+ r = random() * 6;
+ if ((r >= 5) && (old != "e3m1")) return ("e3m1"); // e3m1: Termination Central -- by John Romero
+ if ((r >= 4) && (old != "e3m2")) return ("e3m2"); // e3m2: The Vaults of Zin -- by American McGee
+ if ((r >= 3) && (old != "e3m3")) return ("e3m3"); // e3m3: The Tomb of Terror -- by American McGee
+// e3m4 (Satan's Dark Delight) removed because it sucks for dm
+ if ((r >= 2) && (old != "e3m5")) return ("e3m5"); // e3m5: Wind Tunnels --by Tim Willits
+ if ((r >= 1) && (old != "e3m6")) return ("e3m6"); // e3m6: Chambers of Torment -- by American McGee & Tim Willits
+ return ("e3m7"); // e3m7: The Haunted Halls -- by American McGee
+ } else if (r > 0.2) {
+ r = random() * 8;
+ if ((r >= 7) && (old != "e4m1")) return ("e4m1"); // e4m1: The Sewage System -- by Tim Willits
+ if ((r >= 6) && (old != "e4m2")) return ("e4m2"); // e4m2: The Tower of Despair --by Sandy Petersen
+ if ((r >= 5) && (old != "e4m3")) return ("e4m3"); // e4m3: The Elder God Shrine --by Sandy Petersen
+ if ((r >= 4) && (old != "e4m4")) return ("e4m4"); // e4m4: The Palace of Hate --by Sandy Petersen
+ if ((r >= 3) && (old != "e4m5")) return ("e4m5"); // e4m5: Hell's Atrium --by Sandy Petersen
+ if ((r >= 2) && (old != "e4m6")) return ("e4m6"); // e4m6: The Pain Maze --by Sandy Petersen
+ if ((r >= 1) && (old != "e4m7")) return ("e4m7"); // e4m7: Azure Agony --by Sandy Petersen
+ return ("e4m8"); // e4m8: The Nameless City -- by Sandy Petersen
+ } else {
+ r = random() * 6;
+ if ((r >= 5) && (old != "dm1")) return ("dm1"); // dm1: Place of Two Deaths --by Tim Willits
+ if ((r >= 4) && (old != "dm2")) return ("dm2"); // dm2: Claustrophobopolis --by American McGee
+ if ((r >= 3) && (old != "dm3")) return ("dm3"); // dm3: The Abandoned Base --by John Romero
+ if ((r >= 2) && (old != "dm4")) return ("dm4"); // dm4: The Bad Place --by American McGee
+ if ((r >= 1) && (old != "dm5")) return ("dm5"); // dm5: The Cistern --by Tim Willits
+ return ("dm6"); // dm6: The Dark Zone --by Tim Willits
+ }
+ return("start");
};
/*
@@ -886,6 +1105,7 @@
return;
}
}
+
};
@@ -906,15 +1126,29 @@
IntermissionThink (); // otherwise a button could be missed between
return; // the think tics
}
+ if (self.staydeadtime && self.staydeadtime > time)
+ return;// wait a bit before respawn
+
+// *TEAMPLAY*
+ if (coop && TEAM_STRICT_COOP)
+ return;
if (self.view_ofs == '0 0 0')
return; // intermission or finale
makevectors (self.v_angle); // is this still used
+ if (self.motd_time && self.motd_time < time)
+ MOTD();
+
CheckRules ();
WaterMove ();
+// *TEAMPLAY*
+// TeamCheckLock performs all necessary teamlock checking, and performs all
+// actions needed.
+ TeamCheckLock();
+
if (self.waterlevel == 2)
CheckWaterJump ();
@@ -938,7 +1172,18 @@
if (time < self.pausetime)
self.velocity = '0 0 0';
- if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE)
+// RUNE: If player has rune of elder magic (4), regeneration
+ if (self.player_flag & ITEM_RUNE4_FLAG) {
+ if (self.health < 100 && self.regen_time < time) {
+ self.health = self.health + 2;
+ self.regen_time = time + 0.5;
+ RegenerationSound();
+ }
+ }
+// RUNE
+
+ if(time > self.attack_finished && self.currentammo == 0 &&
+ self.weapon != IT_AXE && self.weapon != IT_HOOK)
{
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
@@ -1026,10 +1271,12 @@
self.invincible_time = 0;
self.invincible_finished = 0;
}
- if (self.invincible_finished > time)
- self.effects = self.effects | EF_DIMLIGHT;
- else
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
+// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
+// client.qc:CheckDimLight
+// if (self.invincible_finished > time)
+// self.effects = self.effects | EF_DIMLIGHT;
+// else
+// self.effects = self.effects - (self.effects & EF_DIMLIGHT);
}
// super damage
@@ -1061,10 +1308,12 @@
self.super_damage_finished = 0;
self.super_time = 0;
}
- if (self.super_damage_finished > time)
- self.effects = self.effects | EF_DIMLIGHT;
- else
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
+// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
+// client.qc:CheckDimLight
+// if (self.super_damage_finished > time)
+// self.effects = self.effects | EF_DIMLIGHT;
+// else
+// self.effects = self.effects - (self.effects & EF_DIMLIGHT);
}
// suit
@@ -1098,6 +1347,8 @@
}
}
+ // Check to see about DIMLIGHT effects
+ CheckDimLight();
};
@@ -1113,6 +1364,8 @@
local float mspeed, aspeed;
local float r;
+ local string num;
+
if (self.view_ofs == '0 0 0')
return; // intermission or finale
if (self.deadflag)
@@ -1143,6 +1396,7 @@
self.jump_flag = self.velocity_z;
CheckPowerups ();
+
};
@@ -1158,6 +1412,26 @@
bprint (self.netname);
bprint (" entered the game\n");
+ dprint("Client ");
+ dprint(self.netname);
+ dprint(" added\n");
+
+ self.motd_time = time + 3;
+ self.motd_count = 0;
+
+ self.suicide_count = 0;
+ self.killed = 0;
+
+// *TEAMPLAY*
+ // If this is our first connection, parm10 is < 0
+ // Set lastteam negative.
+ if(parm10 < 0) {
+ self.lastteam = -50;
+ TeamCheckLock();
+ self.lastteam = self.lastteam + 128; // force a stuff cmd in think
+ }
+
+
// a client connecting during an intermission can cause problems
if (intermission_running)
ExitIntermission ();
@@ -1184,9 +1458,43 @@
bprint (ftos(self.frags));
bprint (" frags\n");
sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
+ DropRune();
+ TeamCaptureDropFlag();
set_suicide_frame ();
};
+void(entity targ, entity attacker, string what) LogPlayerDMDeath =
+{
+ dprint("death ");
+ dprint(targ.netname);
+ dprint(" by ");
+ dprint(attacker.netname);
+ dprint(" ");
+ dprint(what);
+ dprint(" ");
+ dprint(ftos(targ.frags));
+ dprint(" ");
+ dprint(ftos(attacker.frags));
+ dprint("\n");
+};
+
+void (entity targ, string what) LogPlayerDeath =
+{
+ dprint("death ");
+ dprint(targ.netname);
+ dprint(" ");
+ dprint(what);
+ dprint(" ");
+ dprint(ftos(targ.frags));
+ dprint("\n");
+};
+
+// *TEAMPLAY*
+// Prototypes
+
+float(entity targ, entity attacker) TeamFragPenalty;
+void(entity targ, entity attacker) TeamDeathPenalty;
+
/*
===========
ClientObituary
@@ -1197,7 +1505,7 @@
void(entity targ, entity attacker) ClientObituary =
{
local float rnum;
- local string deathstring, deathstring2;
+ local string deathstring, deathstring2, what, s;
rnum = random();
if (targ.classname == "player")
@@ -1210,6 +1518,7 @@
bprint ("\n");
attacker.owner.frags = attacker.owner.frags + 1;
+ LogPlayerDMDeath(targ, attacker.owner, "telefrag");
return;
}
@@ -1220,6 +1529,7 @@
bprint ("'s telefrag\n");
targ.frags = targ.frags - 1;
+ LogPlayerDeath(targ, "telefrag");
return;
}
@@ -1234,12 +1544,20 @@
if (targ.weapon == 64 && targ.waterlevel > 1)
{
bprint (" discharges into the water.\n");
+ LogPlayerDeath(targ, "discharge");
return;
}
- if (targ.weapon == IT_GRENADE_LAUNCHER)
+ if (targ.weapon == IT_GRENADE_LAUNCHER) {
bprint (" tries to put the pin back in\n");
- else
+ LogPlayerDeath(targ, "grenade");
+ } else if (targ.team != targ.lastteam) {
+ //ZOID: try if player was gibbed for changing teams
+ bprint (" changed teams\n");
+ LogPlayerDeath(targ, "teamchange");
+ } else {
bprint (" becomes bored with life\n");
+ LogPlayerDeath(targ, "rocket");
+ }
return;
}
else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) )
@@ -1259,33 +1577,66 @@
}
else
{
+// *TEAMPLAY*
+// TeamFragPenalty returns true if the attacker gets a frag penalty for
+// killing this target. It also deducts frags as needed.
+ if (!TeamFragPenalty(targ, attacker))
+ //ZOID: If in capture mode, do we count regular frags?
+ if ((targ.player_flag & ITEM_ENEMY_FLAG) &&
+ targ.team != attacker.team) {
+ //ZOID: fragged enemy flag carrier
+ attacker.frags = attacker.frags +
+ TEAM_CAPTURE_FRAG_CARRIER_BONUS;
+ sprint(attacker, "Enemy carrier killed: ");
+ s = ftos(TEAM_CAPTURE_FRAG_CARRIER_BONUS);
+ sprint(attacker, s);
+ sprint(attacker, " point bonus\n");
+ } else
attacker.frags = attacker.frags + 1;
+// *TEAMPLAY*
+// TeamDeathPenalty kills the attacker if necessary and adjusts frags to
+// offset the one frag penalty for dying.
+ TeamDeathPenalty(targ, attacker);
+
rnum = attacker.weapon;
if (rnum == IT_AXE)
{
deathstring = " was ax-murdered by ";
deathstring2 = "\n";
+ what = "axe";
+ }
+ if (rnum == IT_HOOK) {
+ if (random() < 0.5)
+ deathstring = " was disembowled by ";
+ else
+ deathstring = " was hooked by ";
+ deathstring2 = "\n";
+ what = "hook";
}
if (rnum == IT_SHOTGUN)
{
deathstring = " chewed on ";
deathstring2 = "'s boomstick\n";
+ what = "shotgun";
}
if (rnum == IT_SUPER_SHOTGUN)
{
deathstring = " ate 2 loads of ";
deathstring2 = "'s buckshot\n";
+ what = "supershotgun";
}
if (rnum == IT_NAILGUN)
{
deathstring = " was nailed by ";
deathstring2 = "\n";
+ what = "nailgun";
}
if (rnum == IT_SUPER_NAILGUN)
{
deathstring = " was punctured by ";
deathstring2 = "\n";
+ what = "supernailgun";
}
if (rnum == IT_GRENADE_LAUNCHER)
{
@@ -1296,6 +1647,13 @@
deathstring = " was gibbed by ";
deathstring2 = "'s grenade\n";
}
+ what = "grenade";
+ }
+ if (rnum == IT_FLAMETHROWER)
+ {
+ deathstring = " is invited to ";
+ deathstring2 = "'s barbeque\n";
+ what = "flamethrower";
}
if (rnum == IT_ROCKET_LAUNCHER)
{
@@ -1306,6 +1664,7 @@
deathstring = " was gibbed by ";
deathstring2 = "'s rocket\n" ;
}
+ what = "rocket";
}
if (rnum == IT_LIGHTNING)
{
@@ -1314,11 +1673,13 @@
deathstring2 = "'s discharge\n";
else
deathstring2 = "'s shaft\n";
+ what = "lightning";
}
bprint (targ.netname);
bprint (deathstring);
bprint (attacker.netname);
bprint (deathstring2);
+ LogPlayerDMDeath(targ, attacker, what);
}
return;
}
@@ -1330,38 +1691,55 @@
// killed by a montser?
if (attacker.flags & FL_MONSTER)
{
- if (attacker.classname == "monster_army")
+ if (attacker.classname == "monster_army") {
bprint (" was shot by a Grunt\n");
- if (attacker.classname == "monster_demon1")
+ LogPlayerDeath(targ, "grunt");
+ } else if (attacker.classname == "monster_demon1") {
bprint (" was eviscerated by a Fiend\n");
- if (attacker.classname == "monster_dog")
+ LogPlayerDeath(targ, "fiend");
+ } else if (attacker.classname == "monster_dog") {
bprint (" was mauled by a Rottweiler\n");
- if (attacker.classname == "monster_dragon")
+ LogPlayerDeath(targ, "dog");
+ } else if (attacker.classname == "monster_dragon") {
bprint (" was fried by a Dragon\n");
- if (attacker.classname == "monster_enforcer")
+ LogPlayerDeath(targ, "dragon");
+ } else if (attacker.classname == "monster_enforcer") {
bprint (" was blasted by an Enforcer\n");
- if (attacker.classname == "monster_fish")
+ LogPlayerDeath(targ, "enforcer");
+ } else if (attacker.classname == "monster_fish") {
bprint (" was fed to the Rotfish\n");
- if (attacker.classname == "monster_hell_knight")
+ LogPlayerDeath(targ, "fish");
+ } else if (attacker.classname == "monster_hell_knight") {
bprint (" was slain by a Death Knight\n");
- if (attacker.classname == "monster_knight")
+ LogPlayerDeath(targ, "deathknight");
+ } else if (attacker.classname == "monster_knight") {
bprint (" was slashed by a Knight\n");
- if (attacker.classname == "monster_ogre")
+ LogPlayerDeath(targ, "knight");
+ } else if (attacker.classname == "monster_ogre") {
bprint (" was destroyed by an Ogre\n");
- if (attacker.classname == "monster_oldone")
+ LogPlayerDeath(targ, "ogre");
+ } else if (attacker.classname == "monster_oldone") {
bprint (" became one with Shub-Niggurath\n");
- if (attacker.classname == "monster_shalrath")
+ LogPlayerDeath(targ, "shub");
+ } else if (attacker.classname == "monster_shalrath") {
bprint (" was exploded by a Vore\n");
- if (attacker.classname == "monster_shambler")
+ LogPlayerDeath(targ, "vore");
+ } else if (attacker.classname == "monster_shambler") {
bprint (" was smashed by a Shambler\n");
- if (attacker.classname == "monster_tarbaby")
+ LogPlayerDeath(targ, "shambler");
+ } else if (attacker.classname == "monster_tarbaby") {
bprint (" was slimed by a Spawn\n");
- if (attacker.classname == "monster_vomit")
+ LogPlayerDeath(targ, "spawn");
+ } else if (attacker.classname == "monster_vomit") {
bprint (" was vomited on by a Vomitus\n");
- if (attacker.classname == "monster_wizard")
+ LogPlayerDeath(targ, "vomitus");
+ } else if (attacker.classname == "monster_wizard") {
bprint (" was scragged by a Scrag\n");
- if (attacker.classname == "monster_zombie")
+ LogPlayerDeath(targ, "scrag");
+ } else if (attacker.classname == "monster_zombie") {
bprint (" joins the Zombies\n");
+ LogPlayerDeath(targ, "zombie");
+ }
return;
}
@@ -1370,26 +1748,31 @@
if (attacker.classname == "explo_box")
{
bprint (" blew up\n");
+ LogPlayerDeath(targ, "explosion");
return;
}
if (attacker.solid == SOLID_BSP && attacker != world)
{
bprint (" was squished\n");
+ LogPlayerDeath(targ, "squished");
return;
}
if (attacker.classname == "trap_shooter" || attacker.classname == "trap_spikeshooter")
{
bprint (" was spiked\n");
+ LogPlayerDeath(targ, "spiked");
return;
}
if (attacker.classname == "fireball")
{
bprint (" ate a lavaball\n");
+ LogPlayerDeath(targ, "fireball");
return;
}
if (attacker.classname == "trigger_changelevel")
{
bprint (" tried to leave\n");
+ LogPlayerDeath(targ, "noexit");
return;
}
@@ -1401,6 +1784,7 @@
bprint (" sleeps with the fishes\n");
else
bprint (" sucks it down\n");
+ LogPlayerDeath(targ, "drowned");
return;
}
else if (rnum == -4)
@@ -1409,6 +1793,7 @@
bprint (" gulped a load of slime\n");
else
bprint (" can't exist on slime alone\n");
+ LogPlayerDeath(targ, "slimed");
return;
}
else if (rnum == -5)
@@ -1416,12 +1801,14 @@
if (targ.health < -15)
{
bprint (" burst into flames\n");
+ LogPlayerDeath(targ, "melted");
return;
}
if (random() < 0.5)
bprint (" turned into hot slag\n");
else
bprint (" visits the Volcano God\n");
+ LogPlayerDeath(targ, "melted");
return;
}
@@ -1430,10 +1817,12 @@
{
targ.deathtype = "";
bprint (" fell to his death\n");
+ LogPlayerDeath(targ, "falling");
return;
}
// hell if I know; he's just dead!!!
+ LogPlayerDeath(targ, "died");
bprint (" died\n");
}
}
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/combat.qc src/combat.qc
--- v106qc/combat.qc Thu Sep 26 11:15:38 1996
+++ src/combat.qc Wed Oct 9 21:12:18 1996
@@ -65,6 +65,7 @@
if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
{ // doors, triggers, etc
+
self.th_die ();
self = oself;
return;
@@ -91,6 +92,12 @@
};
+// *TEAMPLAY*
+// Prototypes
+
+float(entity targ, entity inflictor, entity attacker, float damage) TeamArmorDam;
+float(entity targ, entity inflictor, entity attacker, float damage) TeamHealthDam;
+
/*
============
T_Damage
@@ -115,10 +122,29 @@
// check for quad damage powerup on the attacker
if (attacker.super_damage_finished > time)
damage = damage * 4;
+// RUNE: check for double damage for rune of Black Magic powerup
+ if (attacker.player_flag & ITEM_RUNE2_FLAG)
+ damage = damage * 2;
+// check if target has rune of Earth Magic (half damage)
+ if (targ.player_flag & ITEM_RUNE1_FLAG) {
+ damage = damage / 2;
+ if (targ.invincible_sound < time) {
+ sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
+ targ.invincible_sound = time + 2;
+ }
+ }
+// RUNE
// save damage based on the target's armor level
+// *TEAMPLAY*
+// TeamArmorDam returns true iff the attacker can damage the target's armor
+
+ if (TeamArmorDam(targ, inflictor, attacker, damage))
save = ceil(targ.armortype*damage);
+ else
+ save = 0;
+
if (save >= targ.armorvalue)
{
save = targ.armorvalue;
@@ -163,6 +189,13 @@
// team play damage avoidance
if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
return;
+
+// *TEAMPLAY*
+// TeamHealthDam will return true if the attacker can damage the target's
+// health
+
+ if (!TeamHealthDam(targ, inflictor, attacker, damage))
+ return;
// do the damage
targ.health = targ.health - take;
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/defs.qc src/defs.qc
--- v106qc/defs.qc Thu Sep 26 11:15:38 1996
+++ src/defs.qc Sun Oct 6 15:01:38 1996
@@ -290,7 +290,7 @@
float IT_GRENADE_LAUNCHER = 16;
float IT_ROCKET_LAUNCHER = 32;
float IT_LIGHTNING = 64;
-float IT_EXTRA_WEAPON = 128;
+float IT_FLAMETHROWER = 128;
float IT_SHELLS = 256;
float IT_NAILS = 512;
@@ -309,6 +309,7 @@
float IT_INVULNERABILITY = 1048576;
float IT_SUIT = 2097152;
float IT_QUAD = 4194304;
+float IT_HOOK = 8388608;
// point content values
@@ -409,6 +410,11 @@
float skill;
+entity runespawn;
+float runespawned;
+float capturespawned;
+float teamscored; // non-zero if teams scored
+
//================================================
//
@@ -457,10 +463,16 @@
//
// player only fields
//
+
+// *TEAMPLAY*
+
+.float lastteam; // The last team this player was a member of.
+
.float walkframe;
.float attack_finished;
.float pain_finished;
+.float hook_out;
.float invincible_finished;
.float invisible_finished;
@@ -470,6 +482,8 @@
.float invincible_time, invincible_sound;
.float invisible_time, invisible_sound;
.float super_time, super_sound;
+.float regeneration_sound;//RUNE: Elder Magic
+.float haste_sound;//RUNE: Hell Magic
.float rad_time;
.float fly_sound;
@@ -483,6 +497,26 @@
.float air_finished; // when time > air_finished, start drowning
.float bubble_count; // keeps track of the number of bubbles
.string deathtype; // keeps track of how the player died
+.float player_flag; // misc flags (skins, etc.)
+.float staydeadtime; // how long we should stay dead
+.float regen_time; // time to next regen
+.float rune_notice_time; // last time we notified about multi-runes
+
+// ZOID: Runes
+float ITEM_RUNE1_FLAG = 1;
+float ITEM_RUNE2_FLAG = 2;
+float ITEM_RUNE3_FLAG = 4;
+float ITEM_RUNE4_FLAG = 8;
+float ITEM_RUNE_MASK = 15;
+
+// ZOID: Capture the flag
+float ITEM_ENEMY_FLAG = 16;
+
+.float motd_time;
+.float motd_count;
+
+.float suicide_count;
+.float killed; // have we been killed yet
//
// object stuff
@@ -690,4 +724,9 @@
float(entity targ, entity inflictor) CanDamage;
+
+// Flamethrower
+
+.float onfire;//Flag... set if the entity is on fire
+.entity firewood;// Pointer to an entity that the flame will burn.
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/doors.qc src/doors.qc
--- v106qc/doors.qc Thu Sep 26 11:15:38 1996
+++ src/doors.qc Sun Oct 6 15:01:38 1996
@@ -560,6 +560,7 @@
float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
float SECRET_NO_SHOOT = 8; // only opened by trigger
float SECRET_YES_SHOOT = 16; // shootable even if targeted
+float SECRET_NEVER = 32; // lock it shut
void () fd_secret_use =
@@ -576,6 +577,9 @@
SUB_UseTargets(); // fire all targets / killtargets
+ if (self.spawnflags & SECRET_NEVER)
+ return; // it never opens
+
if (!(self.spawnflags & SECRET_NO_SHOOT))
{
self.th_pain = SUB_Null;
@@ -758,6 +762,7 @@
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
self.classname = "door";
+
setmodel (self, self.model);
setorigin (self, self.origin);
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/flame.qc src/flame.qc
--- v106qc/flame.qc Wed Dec 31 19:00:00 1969
+++ src/flame.qc Sun Oct 6 15:01:38 1996
@@ -0,0 +1,212 @@
+/*
+============================================================================
+
+Quake Flamethrower 1.0
+
+Another groovy patch from Quake Command - http://www.nuc.net/quake
+
+QC Code By : Steve Bond wedge@nuc.net
+
+Apologies in advance... I was unable to comment this as well as I'd have
+liked to. (I used some weird variable names - hope they don't cause problems.
+
+============================================================================
+*/
+
+// Internal declaration
+ void (vector fireorg) SpawnTouchFlame;
+ void () BurnThem;
+
+// Player.qc declaration
+ void () DeathBubblesSpawn;
+
+
+
+// Slightly varied version of DEATHBUBBLES
+void(float num_bubbles, vector bub_origin) NewBubbles =
+{
+local entity bubble_spawner;
+
+ bubble_spawner = spawn();
+ setorigin (bubble_spawner, bub_origin);
+ bubble_spawner.movetype = MOVETYPE_NONE;
+ bubble_spawner.solid = SOLID_NOT;
+ bubble_spawner.nextthink = time + 0.1;
+
+ if (self.classname == "player")
+ bubble_spawner.owner = self;
+ else
+ bubble_spawner.owner = self.firewood;
+
+ bubble_spawner.think = DeathBubblesSpawn;
+ bubble_spawner.bubble_count = num_bubbles;
+ return;
+};
+
+
+/*
+===============
+Burn Them!
+===============
+*/
+void () BurnThem =
+{
+ // CHECK FOR WATER *FIRST*
+ if (self.firewood.waterlevel >= 1)
+ {
+ NewBubbles(6,self.firewood.origin);
+ self.firewood.onfire = FALSE;
+// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
+// client.qc:CheckDimLight
+// self.firewood.effects = self.firewood.effects - EF_DIMLIGHT;
+ remove(self);
+ return;
+ }
+ if (self.firewood.onfire < time) {
+ self.firewood.onfire = FALSE;
+// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
+// client.qc:CheckDimLight
+// self.firewood.effects = self.firewood.effects - EF_DIMLIGHT;
+ remove(self);
+ return;
+ }
+
+ else if (self.firewood.health > 0)
+ {
+ SpawnTouchFlame(self.firewood.origin);
+ T_Damage (self.firewood, self, self.owner, 1);
+ self.nextthink = time + 0.25;
+ }
+ else if (self.firewood.health <= 0) {
+// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
+// client.qc:CheckDimLight
+// self.firewood.effects = self.firewood.effects - EF_DIMLIGHT;
+ self.firewood.onfire = FALSE;
+ remove(self);
+ return;
+ }
+};
+
+
+/*
+================
+SpawnTouchFlame
+================
+*/
+
+void (vector fireorg) SpawnTouchFlame =
+{
+ local entity flame;
+ local float rn;
+
+ flame = spawn ();
+ flame.owner = self;
+ flame.movetype = MOVETYPE_FLYMISSILE;
+ flame.velocity = '0 0 75';
+ flame.solid = SOLID_NOT;
+ flame.classname = "fire";
+ flame.origin = fireorg;
+ flame.think = s_explode1;
+ flame.nextthink = time;
+ setmodel (flame, "progs/s_explod.spr");
+ setsize (flame, '0 0 0', '0 0 0');
+};
+
+/*
+================
+FlameTouch
+================
+*/
+void () FlameTouch =
+{
+ local float rn;
+
+ if (other == self.owner)
+ return;
+
+ if (other.takedamage)
+ {
+ rn = random();
+ // 20% chance
+ if (rn <= 0.2 && !other.onfire)
+ {
+ // Fire stays with whatever it hits
+ if (other.classname == "player")
+ {
+ centerprint(other,"You are on fire! Find WATER!\n");
+ stuffcmd (other,"bf\n");
+ }
+ other.onfire = time + 5; // burn for five secs
+ self.firewood = other;
+ self.think = BurnThem;
+ self.nextthink = time;
+ self.solid = SOLID_NOT;
+ setmodel (self,"");
+// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
+// client.qc:CheckDimLight
+// other.effects = other.effects | EF_DIMLIGHT;
+ }
+ else
+ {
+ SpawnTouchFlame(other.origin);
+ T_Damage (other, self, self.owner, 10 );
+ remove (self);
+ }
+ }
+ else if (other.classname == "worldspawn")
+ {
+ self.velocity = '0 0 0';
+ }
+};
+
+/*
+================
+W_FireFlame
+================
+*/
+void() W_FireFlame =
+{
+ local entity flame;
+ local float rn;
+
+ if (self.waterlevel > 2)
+ {
+ makevectors (self.v_angle);
+ NewBubbles(2, self.origin+v_forward*64);
+
+ rn = random();
+ if (rn < 0.5)
+ sound (self, CHAN_WEAPON, "misc/water1.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_WEAPON, "misc/water2.wav", 1, ATTN_NORM);
+
+ return;
+ }
+
+ // Take away a shell
+ self.currentammo = self.ammo_shells = self.ammo_shells - 1;
+
+ sound (self, CHAN_WEAPON, "hknight/hit.wav", 1, ATTN_NORM);
+
+ flame = spawn ();
+ flame.owner = self;
+ flame.movetype = MOVETYPE_FLYMISSILE;
+ flame.solid = SOLID_BBOX;
+ flame.classname = "fire";
+
+// set flame speed
+
+ makevectors (self.v_angle);
+
+ flame.velocity = aim(self, 10000);
+ flame.velocity = flame.velocity * 300;
+
+ flame.touch = FlameTouch;
+
+ flame.think = s_explode1;
+ flame.nextthink = time + 0.15;
+
+ setmodel (flame, "progs/s_explod.spr");
+ setsize (flame, '0 0 0', '0 0 0');
+ setorigin (flame, self.origin + v_forward * 16 + '0 0 16');
+};
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/hook.qc src/hook.qc
--- v106qc/hook.qc Wed Dec 31 19:00:00 1969
+++ src/hook.qc Sat Oct 12 21:23:41 1996
@@ -0,0 +1,228 @@
+
+/************\
+* BreakChain *
+\************/
+
+void (entity Head) BreakChain =
+{
+ local entity link;
+
+ link = Head.goalentity;
+ while (link != world)
+ {
+ Head = link.goalentity;
+ remove (link);
+ link = Head;
+ }
+};
+
+/*********\
+* LinkPos *
+\*********/
+
+void () LinkPos =
+{
+ makevectors (self.enemy.angles);
+ setorigin (self, self.owner.origin + ( ( ( self.enemy.origin +
+ (v_up * 16 * (!self.enemy.button2)) + (v_forward * 16) ) - self.owner.origin ) *
+ ( self.weapon ) ) );
+ self.nextthink = time + 0.1;
+};
+
+/***********\
+* MakeChain *
+\***********/
+
+entity (entity head, entity tail, float num) MakeChain =
+{
+ local entity link, prevlink;
+ local float linknum;
+
+ linknum = num;
+ num = num + 1;
+ prevlink = world;
+ while (linknum > 0)
+ {
+ link = spawn();
+
+ link.goalentity = prevlink;
+ prevlink = link;
+
+ link.owner = head;
+ link.enemy = tail;
+ link.weapon = linknum / num;
+ link.movetype = MOVETYPE_NOCLIP;
+ link.solid = SOLID_NOT;
+ link.angles_z = 51 * linknum;
+ link.angles_y = 41 * linknum;
+ link.angles_x = 31 * linknum;
+ link.avelocity = '310 410 510';
+ setmodel (link, "progs/s_spike.mdl");
+ setsize (link, '0 0 0', '0 0 0');
+ makevectors (tail.angles);
+ setorigin (link, head.origin + ( ( ( tail.origin
+ + (v_up * 16 * (!tail.button2)) + ( v_forward * 16 ) ) - head.origin )
+ * ( link.weapon ) ) );
+ link.nextthink = time + 0.1;
+ link.think = LinkPos;
+ linknum = linknum - 1;
+ }
+ return link;
+};
+
+
+/************\
+* HookVanish *
+\************/
+
+void () HookVanish =
+{
+ self.owner.hook_out = FALSE;
+/*
+ if (self.enemy.classname == "player")
+ self.enemy.attack_finished = time + 0.1;
+*/
+ BreakChain (self);
+ remove (self);
+};
+
+/**********\
+* HookPull *
+\**********/
+
+void () HookPull =
+{
+ local vector vel, spray;
+ local float v;
+
+ if ((!self.owner.button0 && (self.owner.weapon == IT_HOOK)) ||
+ (self.owner.teleport_time > time ) || self.owner.deadflag ) {
+ HookVanish();
+ return;
+ } else {
+ if (self.enemy.takedamage) {
+ // don't hurt teammates
+ if (self.enemy.classname != "player" || !teamplay ||
+ self.enemy.team != self.owner.team) {
+ sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
+ T_Damage (self.enemy, self, self.owner, 1);
+ makevectors (self.v_angle);
+ spray_x = 100 * crandom();
+ spray_y = 100 * crandom();
+ spray_z = 100 * crandom() + 50;
+ SpawnBlood (self.origin, spray, 20);
+ }
+ if (self.enemy.solid == SOLID_SLIDEBOX) {
+ self.velocity = '0 0 0';
+ setorigin (self, self.enemy.origin +
+ self.enemy.mins +
+ (self.enemy.size * 0.5));
+ } else {
+ self.velocity = self.enemy.velocity;
+ }
+ } else {
+ self.velocity = self.enemy.velocity;
+ }
+ if (self.enemy.solid == SOLID_NOT) {
+ HookVanish();
+ return;
+ }
+ makevectors (self.owner.angles);
+ vel = self.origin - ( self.owner.origin + (v_up * 16 *
+ (!self.owner.button2)) + (v_forward * 16));
+ v = vlen (vel);
+ if (v <= 100)
+ vel = normalize(vel) * v * 10;
+ if ( v > 100 )
+ vel = normalize(vel) * 1000;
+ self.owner.velocity = vel;
+ self.nextthink = time + 0.1;
+ }
+};
+
+/**************\
+* T_ChainTouch *
+\**************/
+
+void() T_ChainTouch =
+{
+ if (other == self.owner)
+ return; // don't attach to owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY) {
+ HookVanish();
+ return;
+ }
+
+ if (other.takedamage) {
+ // don't damage teammates
+ if (other.classname != "player" || !teamplay ||
+ other.team != self.owner.team) {
+ if (other.classname == "player")
+ other.axhitme = 1; // make axe noise
+ else
+ sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
+ T_Damage (other, self, self.owner, 10 );
+ SpawnBlood (self.origin, self.velocity, 10);
+ } else
+ sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
+ } else {
+ sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
+ self.avelocity = '0 0 0';
+ }
+
+ if (!self.owner.button0) {
+ HookVanish();
+ return;
+ } else {
+ if (other.solid == SOLID_SLIDEBOX) {
+ setorigin (self, other.origin + other.mins +
+ (other.size * 0.5));
+ self.velocity = '0 0 0';
+ } else {
+ self.velocity = other.velocity;
+ }
+ self.weapon = other.nextthink - time;
+ self.enemy = other;
+ self.nextthink = time + 0.1;
+ self.think = HookPull;
+ self.touch = SUB_Null;
+ }
+};
+
+/*************\
+* W_FireChain *
+\*************/
+
+void() W_FireChain =
+{
+ local entity hook;
+
+ self.hook_out = TRUE;
+ hook = spawn ();
+ hook.owner = self;
+ hook.movetype = MOVETYPE_FLY;
+ hook.solid = SOLID_BBOX;
+
+// set hook speed
+
+ makevectors (self.v_angle);
+ hook.velocity = aim(self, 1000);
+ hook.velocity = hook.velocity * 1000;
+ hook.angles = vectoangles(hook.velocity);
+ hook.avelocity = '0 0 -500';
+
+ hook.touch = T_ChainTouch;
+
+// set hook sound
+ hook.nextthink = time + 5;
+ hook.think = HookVanish;
+
+ setmodel (hook, "progs/v_spike.mdl");
+ setsize (hook, '0 0 0', '0 0 0');
+ setorigin (hook, self.origin + (v_forward*16) + '0 0 16' );
+
+ sound (self, CHAN_WEAPON, "hknight/hit.wav", 1, ATTN_NORM);
+
+ hook.goalentity = MakeChain (hook, self, 2);
+};
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/items.qc src/items.qc
--- v106qc/items.qc Thu Sep 26 11:15:38 1996
+++ src/items.qc Mon Oct 14 01:46:27 1996
@@ -168,10 +168,13 @@
return;
}
+// ZOID--remove uncessary msgs
+ if (!deathmatch) {
sprint(other, "You receive ");
s = ftos(self.healamount);
sprint(other, s);
sprint(other, " health\n");
+ }
// health touch sound
sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
@@ -207,8 +210,9 @@
{
other = self.owner;
- if (other.health > other.max_health)
- {
+//ZOID: player doesn't rot if they have Elder Magic rune
+ if (other.health > other.max_health &&
+ !(other.player_flag & ITEM_RUNE4_FLAG)) {
other.health = other.health - 1;
self.nextthink = time + 1;
return;
@@ -275,6 +279,8 @@
self.nextthink = time + 20;
self.think = SUB_regen;
+//ZOID--remove unneccessary msgs
+ if (!deathmatch)
sprint(other, "You got armor\n");
// armor touch sound
sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
@@ -376,6 +382,8 @@
local float or, nr;
// change self.weapon if desired
+ if (self.weapon == IT_HOOK && self.button0)
+ return; // never change if we pulled ourselves to it.
or = RankForWeapon (self.weapon);
nr = RankForWeapon (new);
if ( nr < or )
@@ -415,6 +423,8 @@
return;
hadammo = other.ammo_nails;
new = IT_NAILGUN;
+// *TEAMPLAY*
+ if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
other.ammo_nails = other.ammo_nails + 30;
}
else if (self.classname == "weapon_supernailgun")
@@ -423,6 +433,8 @@
return;
hadammo = other.ammo_rockets;
new = IT_SUPER_NAILGUN;
+// *TEAMPLAY*
+ if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
other.ammo_nails = other.ammo_nails + 30;
}
else if (self.classname == "weapon_supershotgun")
@@ -431,6 +443,8 @@
return;
hadammo = other.ammo_rockets;
new = IT_SUPER_SHOTGUN;
+// *TEAMPLAY*
+ if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
other.ammo_shells = other.ammo_shells + 5;
}
else if (self.classname == "weapon_rocketlauncher")
@@ -439,6 +453,8 @@
return;
hadammo = other.ammo_rockets;
new = IT_ROCKET_LAUNCHER;
+// *TEAMPLAY*
+ if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
other.ammo_rockets = other.ammo_rockets + 5;
}
else if (self.classname == "weapon_grenadelauncher")
@@ -446,7 +462,11 @@
if (leave && (other.items & IT_GRENADE_LAUNCHER) )
return;
hadammo = other.ammo_rockets;
+// FLAMETHROWER
+ other.items = other.items | IT_FLAMETHROWER;
new = IT_GRENADE_LAUNCHER;
+// *TEAMPLAY*
+ if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
other.ammo_rockets = other.ammo_rockets + 5;
}
else if (self.classname == "weapon_lightning")
@@ -455,14 +475,20 @@
return;
hadammo = other.ammo_rockets;
new = IT_LIGHTNING;
+// *TEAMPLAY*
+ if ( !( coop && (teamplay & TEAM_DROP_ITEMS) ) )
other.ammo_cells = other.ammo_cells + 15;
}
else
objerror ("weapon_touch: unknown classname");
+//ZOID--remove unnessary msgs
+ if (!deathmatch) {
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other, "\n");
+ }
+
// weapon touch sound
sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
stuffcmd (other, "bf\n");
@@ -645,9 +671,12 @@
bound_other_ammo ();
+//ZOID--remove unnessary msgs
+ if (!deathmatch) {
sprint (other, "You got the ");
sprint (other, self.netname);
sprint (other, "\n");
+ }
// ammo touch sound
sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
stuffcmd (other, "bf\n");
@@ -1237,6 +1266,9 @@
return;
if (other.health <= 0)
return;
+ //don't let self pick it up for a sec
+ if ((other == self.owner) && ( (self.nextthink - time) > 118 ) )
+ return;
acount = 0;
sprint (other, "You get ");
@@ -1339,9 +1371,22 @@
item = spawn();
item.origin = self.origin - '0 0 24';
+ // if weapon is flamethrower, change quickly to grenade launcher
+ if (self.weapon == IT_FLAMETHROWER)
+ self.weapon = IT_GRENADE_LAUNCHER;
+
+ item.items = 0; // none by default
+
+//ZOID--axe and hook don't go into backpack
+ if (self.weapon != IT_HOOK || self.weapon != IT_AXE)
item.items = self.weapon;
- if (item.items == IT_AXE)
- item.netname = "Axe";
+
+ // If weapon was grenade launcher, flamethrower goes in backpack too
+ if (self.weapon == IT_GRENADE_LAUNCHER)
+ item.items = item.items | IT_FLAMETHROWER;
+
+// if (item.items == IT_AXE)
+// item.netname = "Axe";
else if (item.items == IT_SHOTGUN)
item.netname = "Shotgun";
else if (item.items == IT_SUPER_SHOTGUN)
@@ -1378,3 +1423,237 @@
item.nextthink = time + 120; // remove after 2 minutes
item.think = SUB_Remove;
};
+
+/*----------------------------------------------------------------------
+ The Rune Game modes
+
+ Rune 1 - Earth Magic
+ resistance
+ Rune 2 - Black Magic
+ strength
+ Rune 3 - Hell Magic
+ haste
+ Rune 4 - Elder Magic
+ regeneration
+
+ ----------------------------------------------------------------------*/
+
+entity() SelectRuneSpawnPoint =
+{
+ runespawn = find(runespawn, classname, "info_player_deathmatch");
+ if (runespawn == world)
+ runespawn = find (runespawn, classname, "info_player_deathmatch");
+ if (runespawn == world)
+ error("no info_player_deathmatch to spawn rune");
+ return runespawn;
+};
+
+void() RuneTouch =
+{
+ local string s;
+ local float best;
+ local entity stemp;
+
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+ if (other.player_flag & ITEM_RUNE_MASK) {
+ if (other.rune_notice_time < time) {
+ centerprint(other, "You already have a rune.\n");
+ other.rune_notice_time = time + 5;
+ }
+ return; // one per customer
+ }
+
+ other.player_flag = other.player_flag | self.player_flag;
+
+ // notification of rune, no nofity in team mode
+ if (self.player_flag & ITEM_RUNE1_FLAG) {
+ bprint(other.netname);
+// bprint(" got the rune of Earth Magic!\n");
+ bprint(" got the rune of ┼ß≥⌠Φ ═ßτΘπ!\n");
+// centerprint(other, "You got the Earth Magic Rune!\n\nRESISTANCE\n\nYou now take half damage!");
+ centerprint(other, "You got the ┼ß≥⌠Φ ═ßτΘπ Rune!\n\n╥σ≤Θ≤⌠ßεπσ\n\nYou now take half damage!");
+ }
+ if (self.player_flag & ITEM_RUNE2_FLAG) {
+ bprint(other.netname);
+// bprint(" got the rune of Black Magic!\n");
+ bprint(" got the rune of ┬∞ßπδ ═ßτΘπ!\n");
+// centerprint(other, "You got the Black Magic Rune!\n\nSTRENGTH\n\nYou now dish out double damage!");
+ centerprint(other, "You got the ┬∞ßπδ ═ßτΘπ Rune!\n\n╙⌠≥σετ⌠Φ\n\nYou now dish out double damage!");
+ }
+ if (self.player_flag & ITEM_RUNE3_FLAG) {
+ bprint(other.netname);
+// bprint(" got the rune of Hell Magic!\n");
+ bprint(" got the rune of ╚σ∞∞ ═ßτΘπ!\n");
+// centerprint(other, "You got the Hell Magic Rune!\n\nHASTE\n\nYou now fire twice fast!");
+ centerprint(other, "You got the ╚σ∞∞ ═ßτΘπ Rune!\n\n╚ß≤⌠σ\n\nYou now fire twice fast!");
+ }
+ if (self.player_flag & ITEM_RUNE4_FLAG) {
+ bprint(other.netname);
+// bprint(" got the rune of Elder Magic!\n");
+ bprint(" got the rune of ┼∞Σσ≥ ═ßτΘπ!\n");
+// centerprint(other, "You got the Elder Magic Rune!\n\nREGENERATION\n\nYou now regenerate!");
+ centerprint(other, "You got the ┼∞Σσ≥ ═ßτΘπ Rune!\n\n╥στσεσ≥ß⌠Θ∩ε\n\nYou now regenerate!");
+ }
+
+ // backpack touch sound
+ sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+ remove(self);
+};
+
+void (float flag) Do_DropRune;
+
+void() RuneRespawn =
+{
+ local entity oself;
+
+ oself = self;
+
+ // choose random starting points
+ self = SelectRuneSpawnPoint();
+ Do_DropRune(oself.player_flag);
+
+ remove(oself);
+};
+
+void (float flag) Do_DropRune =
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.player_flag = flag;
+
+ item.velocity_z = 400;
+ item.velocity_x = -500 + (random() * 1000);
+ item.velocity_y = -500 + (random() * 1000);
+
+ item.flags = FL_ITEM;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ if (flag & ITEM_RUNE1_FLAG)
+ setmodel (item, "progs/end1.mdl");
+ else if (flag & ITEM_RUNE2_FLAG)
+ setmodel (item, "progs/end2.mdl");
+ else if (flag & ITEM_RUNE3_FLAG)
+ setmodel (item, "progs/end3.mdl");
+ else if (flag & ITEM_RUNE4_FLAG)
+ setmodel (item, "progs/end4.mdl");
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = RuneTouch;
+
+ item.nextthink = time + 120; /* if no one touches it in two minutes,
+ respawn it somewhere else, so inaccessible ones will come 'back' */
+ item.think = RuneRespawn;
+};
+
+/*
+===============
+Droprune
+self is player
+===============
+*/
+void() DropRune =
+{
+ if (self.player_flag & ITEM_RUNE1_FLAG)
+ Do_DropRune(ITEM_RUNE1_FLAG);
+ if (self.player_flag & ITEM_RUNE2_FLAG)
+ Do_DropRune(ITEM_RUNE2_FLAG);
+ if (self.player_flag & ITEM_RUNE3_FLAG)
+ Do_DropRune(ITEM_RUNE3_FLAG);
+ if (self.player_flag & ITEM_RUNE4_FLAG)
+ Do_DropRune(ITEM_RUNE4_FLAG);
+ self.player_flag = self.player_flag - (self.player_flag & ITEM_RUNE_MASK);
+};
+
+/*
+================
+SpawnRunes
+spawn all the runes
+self is the entity that was created for us, we remove it
+================
+*/
+void() SpawnRunes =
+{
+ local entity oself;
+ local float i;
+
+ if (runespawned) {
+ remove(self);
+ return;
+ }
+
+ oself = self;
+
+ // choose random starting points
+ i = random() * 10;
+ while (i > 0) {
+ self = SelectRuneSpawnPoint();
+ i = i - 1;
+ }
+
+ self = SelectRuneSpawnPoint();
+ Do_DropRune(ITEM_RUNE1_FLAG);
+ self = SelectRuneSpawnPoint();
+ Do_DropRune(ITEM_RUNE2_FLAG);
+ self = SelectRuneSpawnPoint();
+ Do_DropRune(ITEM_RUNE3_FLAG);
+ self = SelectRuneSpawnPoint();
+ Do_DropRune(ITEM_RUNE4_FLAG);
+
+ runespawned = 1;
+
+ remove(oself);
+};
+
+// ZOID Capture the flag
+void() item_flag_team1 =
+{
+ if (!deathmatch || !(cvar("teamplay") & TEAM_CAPTURE_FLAG)) {
+ remove(self);
+ return;
+ }
+
+ self.team = TEAM_COLOR1 + 1;
+ self.cnt = 1; // it's at home base
+ precache_model ("progs/w_g_key.mdl");
+ setmodel (self, "progs/w_g_key.mdl");
+ self.touch = TeamCaptureFlagTouch;
+ self.items = IT_KEY2;
+ precache_sound ("misc/medkey.wav");
+ precache_sound ("doors/meduse.wav");
+ self.noise = "misc/medkey.wav";
+ setsize(self, '-16 -16 -24', '16 16 32');
+ // make it glow
+ self.effects = self.effects | EF_DIMLIGHT;
+ StartItem();
+};
+
+void() item_flag_team2 =
+{
+ if (!deathmatch || !(cvar("teamplay") & TEAM_CAPTURE_FLAG)) {
+ remove(self);
+ return;
+ }
+
+ self.team = TEAM_COLOR2 + 1;
+ self.cnt = 1; // it's at home base
+ precache_model ("progs/w_s_key.mdl");
+ setmodel (self, "progs/w_s_key.mdl");
+ self.touch = TeamCaptureFlagTouch;
+ self.items = IT_KEY1;
+ precache_sound ("misc/medkey.wav");
+ precache_sound ("doors/meduse.wav");
+ self.noise = "misc/medkey.wav";
+ setsize(self, '-16 -16 -24', '16 16 32');
+ // make it glow
+ self.effects = self.effects | EF_DIMLIGHT;
+ StartItem();
+};
+
+
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/player.qc src/player.qc
--- v106qc/player.qc Thu Sep 26 11:15:40 1996
+++ src/player.qc Sun Oct 6 15:01:39 1996
@@ -1,5 +1,8 @@
void() bubble_bob;
+void() W_FireChain;
+void() player_chain5;
+void() player_chain4;
/*
==============================================================================
@@ -98,7 +101,7 @@
return;
}
- if (self.weapon == IT_AXE)
+ if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
{
if (self.walkframe >= 12)
self.walkframe = 0;
@@ -123,7 +126,7 @@
return;
}
- if (self.weapon == IT_AXE)
+ if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
{
if (self.walkframe == 6)
self.walkframe = 0;
@@ -167,6 +170,41 @@
void() player_axed3 = [$axattd3, player_axed4 ] {self.weaponframe=7;W_FireAxe();};
void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;};
+void() player_chain1= [$axattd1, player_chain2 ] {self.weaponframe=2;};
+void() player_chain2= [$axattd2, player_chain3 ] {self.weaponframe=3;W_FireChain();};
+
+void() player_chain3= [$axattd3, player_chain3 ]
+{
+ self.weaponframe=3;
+ if (!self.hook_out)
+ {
+ player_chain5();
+ return;
+ }
+ if (vlen(self.velocity) >= 750)
+ {
+ player_chain4();
+ return;
+ }
+};
+
+void() player_chain4= [$deathc4, player_chain4 ]
+{
+ self.weaponframe=4;
+ if (!self.hook_out)
+ {
+ player_chain5();
+ return;
+ }
+ if (vlen(self.velocity) < 750)
+ {
+ player_chain3();
+ return;
+ }
+};
+
+void() player_chain5= [$axattd4, player_run ] {self.weaponframe=5;};
+
//============================================================================
@@ -342,7 +380,7 @@
if (self.invisible_finished > time)
return; // eyes don't have pain frames
- if (self.weapon == IT_AXE)
+ if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
player_axpain1 ();
else
player_pain1 ();
@@ -505,12 +543,14 @@
if (damage_attacker.classname == "teledeath")
{
+ self.staydeadtime = time + 2 + (random() * 3);
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
return;
}
if (damage_attacker.classname == "teledeath2")
{
+ self.staydeadtime = time + 3 + (random() * 6);
sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
return;
}
@@ -532,9 +572,16 @@
self.radsuit_finished = 0;
self.modelindex = modelindex_player; // don't use eyes
- if (deathmatch || coop)
+ if (deathmatch || coop) {
DropBackpack();
+ DropRune();
+ TeamCaptureDropFlag();
+ }
+ if (self.killed == 2)
+ self.killed = 0;
+ else
+ self.killed = 1;
self.weaponmodel="";
self.view_ofs = '0 0 -8';
self.deadflag = DEAD_DYING;
@@ -555,7 +602,7 @@
self.angles_x = 0;
self.angles_z = 0;
- if (self.weapon == IT_AXE)
+ if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
{
player_die_ax1 ();
return;
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/progs.src src/progs.src
--- v106qc/progs.src Sun Oct 6 16:01:11 1996
+++ src/progs.src Mon Oct 7 20:43:03 1996
@@ -1,12 +1,19 @@
progs.dat
defs.qc
+teamplay.qc // Compile the teamplay file
subs.qc
fight.qc
ai.qc
combat.qc
items.qc
+
weapons.qc
+
+flame.qc
+
+telefrag.qc // from server modules
+
world.qc
client.qc
player.qc
@@ -33,3 +40,4 @@
shalrath.qc // registered
enforcer.qc // registered
oldone.qc // registered
+hook.qc
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/teamplay.qc src/teamplay.qc
--- v106qc/teamplay.qc Wed Dec 31 19:00:00 1969
+++ src/teamplay.qc Mon Oct 14 01:51:32 1996
@@ -0,0 +1,1180 @@
+/* teamplay.qc
+
+ From
+ The Comlete Enhanced Teamplay
+
+ John Spickes -- jspickes@eng.umd.edu
+
+ $Id: teamplay.qc 1.17 1996/08/17 16:52:45 jspickes Exp $
+
+ $Log: teamplay.qc $
+ Revision 1.17 1996/08/17 16:52:45 jspickes
+ Fixed a problem with displaying the current team settings that could cause
+ the wrong output when teamplay was negative. Also added code to indicate
+ when ID's silly teamplay code is being used.
+
+ Revision 1.16 1996/08/17 00:41:52 jspickes
+ Turned off strict coop by default.
+ Fixed a bug that could have caused strange behavior if TEAM_COLOR* was
+ set to -2.
+
+ Revision 1.15 1996/08/17 00:34:17 jspickes
+ Added instructions on drop-item use in current settings output.
+ Fixed a problem that would allow you to drop lots of backpacks with
+ nothing in them.
+
+*/
+
+/** Defs **/
+
+/** MODIFIABLE CONSTANTS **/
+
+float TEAM_DEFAULT_PENALTY = 1; // Default frag penalty
+float TEAM_STRICT_COOP = 0; // Strict Coop
+
+// Allowed team colors
+// -1 indicates no color
+
+float TEAM_COLOR1 = 4;
+float TEAM_COLOR2 = 13;
+float TEAM_COLOR3 = -1;
+float TEAM_COLOR4 = -1;
+
+/** End of MODIFIABLE CONSTANTS **/
+
+// Globals
+
+entity team1_lastspawn;
+entity team2_lastspawn;
+
+// Teamplay bitfield entries
+
+float TEAM_HEALTH_PROTECT = 1; // No health damage from friendly fire
+float TEAM_ARMOR_PROTECT = 2; // No armor damage from friendly fire
+float TEAM_ATTACKER_DAMAGE = 4; // Attacker takes damage from hitting teammates
+float TEAM_FRAG_PENALTY = 8; // One frag penalty for killing teammate
+float TEAM_DEATH_PENALTY = 16; // Die when you kill a teammate.
+float TEAM_LOCK_COLORS = 32; // Allow only team colors
+float TEAM_STATIC_TEAMS = 64; // Don't allow players to switch teams
+float TEAM_DROP_ITEMS = 128; // Allow players to drop packs and
+float TEAM_CAPTURE_FLAG = 256; // Play capture the flag
+
+float TEAM_CAPTURE_CAPTURE_BONUS = 12; // what you get for capture
+float TEAM_CAPTURE_TEAM_BONUS = 12; // what your team gets for capture
+float TEAM_CAPTURE_RECOVERY_BONUS = 1; // what you get for recovery
+float TEAM_CAPTURE_FLAG_BONUS = 1; // what you get for picking up enemy flag
+float TEAM_CAPTURE_FRAG_CARRIER_BONUS = 3; // what you get for fragging
+ //enemy flag carrier
+
+// Prototypes
+float() W_BestWeapon;
+void() W_SetCurrentAmmo;
+void() bound_other_ammo;
+void(float o, float n) Deathmatch_Weapon;
+void() BackpackTouch;
+
+// Return a name for the color of a team
+string(float Team) GetTeamColor =
+{
+ if(Team == 0) return("Blue");
+ else if(Team == 1) return("Steel blue");
+ else if(Team == 2) return("Brown");
+ else if(Team == 3) return("Baby blue");
+ else if(Team == 4) return("Green");
+ else if(Team == 5) return("Red");
+ else if(Team == 6) return("Olive");
+ else if(Team == 7) return("Orange");
+ else if(Team == 8) return("Peech");
+ else if(Team == 9) return("Purple");
+ else if(Team == 10) return("Majenta");
+ else if(Team == 11) return("Grey");
+ else if(Team == 12) return("Aqua");
+ else if(Team == 13) return("Yellow");
+ else if(Team == 14) return("Blue");
+ return "Unknown";
+};
+
+
+/*
+================
+TeamPrintSettings
+
+Print out current teamplay options
+================
+*/
+
+void() TeamPrintSettings =
+{
+ local string s;
+
+ sprint(self,"The following Teamplay options are set:\n");
+
+ if(teamplay < 0)
+ {
+ sprint(self, "Frag penalty manually set to ");
+ s = ftos(teamplay);
+ sprint(self, s);
+ sprint(self, "\n");
+ return;
+ }
+
+ if(!teamplay)
+ {
+ sprint(self, "None\n");
+ return;
+ }
+
+ if(1 == teamplay)
+ {
+ sprint(self, "ID's original teamplay 1\n");
+ return;
+ }
+
+ if(teamplay & TEAM_HEALTH_PROTECT)
+ sprint(self, "Health-Protect ");
+
+ if(teamplay & TEAM_ARMOR_PROTECT)
+ sprint(self, "Armor-Protect ");
+
+ if(teamplay & TEAM_ATTACKER_DAMAGE)
+ sprint(self, "Mirror-Damage ");
+
+ if(teamplay & TEAM_FRAG_PENALTY)
+ sprint(self, "Frag-Penalty ");
+
+ if(teamplay & TEAM_DEATH_PENALTY)
+ sprint(self, "Death-Penalty ");
+
+ if(teamplay & TEAM_LOCK_COLORS)
+ sprint(self, "Lock-Colors ");
+
+ if(teamplay & TEAM_STATIC_TEAMS)
+ sprint(self, "Static-Teams ");
+
+ if(teamplay & TEAM_DROP_ITEMS)
+ sprint(self, "Drop-Items (Backpack Impulse 20, Weapon Impulse 21) ");
+
+ if(teamplay & TEAM_CAPTURE_FLAG)
+ sprint(self, "Capture-The-Flag ");
+
+ sprint(self, "\n");
+};
+
+/*
+================
+TeamArmorDam
+
+Return TRUE if the target's armor can take damage from this attacker.
+================
+*/
+
+float(entity targ, entity inflictor, entity attacker, float damage) TeamArmorDam =
+{
+ if( teamplay < 0 )
+ return TRUE;
+ if( (teamplay & TEAM_ARMOR_PROTECT) && (attacker.team == targ.team) && (attacker != targ) && (targ.team > 0) )
+ {
+ // Armor is protected
+ return FALSE;
+ }
+ return TRUE;
+};
+
+/*
+================
+TeamHealthDam
+
+Return TRUE if the target can take health damage from this attacker.
+================
+*/
+
+float(entity targ, entity inflictor, entity attacker, float damage) TeamHealthDam =
+{
+ if( teamplay < 0 )
+ {
+ return TRUE;
+ }
+ if( (attacker.team == targ.team) && (attacker != targ) && (targ.team > 0) )
+ {
+ // Attacker and target are on the same team.
+ if( teamplay & TEAM_ATTACKER_DAMAGE )
+ {
+ // Damage applied to teammate.
+ T_Damage(attacker, inflictor, attacker, damage);
+ }
+ if( teamplay & TEAM_HEALTH_PROTECT )
+ {
+ // Health is protected
+ return FALSE;
+ }
+ }
+ return TRUE;
+};
+
+/*
+================
+TeamPFrags
+
+Return the number of frags we should penalize attacker for killing targ.
+================
+*/
+
+float(entity targ, entity attacker) TeamPFrags =
+{
+ if( teamplay < 0 )
+ return (-1 * teamplay);
+ if( (targ.team > 0) && (targ != attacker) && (targ.team == attacker.team) )
+ {
+ // targ and attacker are on the same team
+ if( teamplay < 0 )
+ {
+ // teamplay indicates frag penalty
+ return ( -1 * teamplay );
+ }
+ if( teamplay & TEAM_FRAG_PENALTY )
+ {
+ // default penalty
+ return TEAM_DEFAULT_PENALTY;
+ }
+ }
+ // No frag penalty
+ return 0;
+};
+
+/*
+================
+TeamFragPenalty
+
+If attacker should be penalized for killing targ, penalize attacker
+and return TRUE.
+================
+*/
+
+float(entity targ, entity attacker) TeamFragPenalty =
+{
+ local float f;
+
+ f = TeamPFrags(targ, attacker);
+
+ if( f )
+ {
+ // We should penalize some frags.
+ attacker.frags = attacker.frags - f;
+ return TRUE;
+ }
+ // No penalty
+ return FALSE;
+};
+
+/*
+=================
+TeamDeathPenalty
+
+If attacker should be killed for killing targ, kill attacker and
+add a frag to offset the one attacker will lose for killing himself.
+*/
+
+void(entity targ, entity attacker) TeamDeathPenalty =
+{
+ //Don't kill anyone if teamplay is negative.
+ if ( teamplay < 0 )
+ return;
+
+ if ( (teamplay & TEAM_DEATH_PENALTY) && (targ.team > 0) && (attacker != targ) && (attacker.team == targ.team) )
+ {
+ //We should kill the attacker.
+ T_Damage(attacker,attacker,attacker,1000);
+ //Add a frag to offset the self-kill penalty.
+ attacker.frags = attacker.frags + 1;
+ }
+};
+
+/*
+==================
+TeamColorIsLegal
+
+Return TRUE if the indicated color is legal
+==================
+*/
+float(float color) TeamColorIsLegal =
+{
+ // All colors are legal if teamplay is negative.
+ if( teamplay < 0 )
+ return TRUE;
+ // All colors are legal if TEAM_LOCK_COLORS is off.
+ if( !(teamplay & TEAM_LOCK_COLORS) )
+ return TRUE;
+ if( (color == TEAM_COLOR1) && (TEAM_COLOR1 >= 0) )
+ return TRUE;
+ if( (color == TEAM_COLOR2) && (TEAM_COLOR2 >= 0) )
+ return TRUE;
+ if( (color == TEAM_COLOR3) && (TEAM_COLOR3 >= 0) )
+ return TRUE;
+ if( (color == TEAM_COLOR4) && (TEAM_COLOR4 >= 0) )
+ return TRUE;
+};
+
+/*
+==================
+TeamCheckTeam
+
+Check if the team self is on is legal, and put self in a legal team if not.
+Return TRUE if the current color is ok, FALSE if we have to set it.
+==================
+*/
+float() TeamCheckTeam =
+{
+ local float TEAM1;
+ local float TEAM2;
+ local float TEAM3;
+ local float TEAM4;
+
+ local float newcolor;
+ local float t;
+
+ local entity p;
+
+ local string n;
+
+
+ if( self.lastteam >= 0 )
+ {
+ if(TeamColorIsLegal(self.team - 1))
+ return TRUE;
+ }
+
+ // Assign the player to a team.
+
+ // Sum the players on all the teams.
+
+ TEAM1 = 0;
+ TEAM2 = 0;
+ TEAM3 = 0;
+ TEAM4 = 0;
+
+ p = find (world, classname, "player");
+
+ while(p)
+ {
+ if( (TEAM_COLOR1 >= 0) && (p.team == (TEAM_COLOR1 +1)) )
+ TEAM1 = TEAM1 + 1;
+ if( (TEAM_COLOR2 >= 0) && (p.team == (TEAM_COLOR2 +1)) )
+ TEAM2 = TEAM2 + 1;
+ if( (TEAM_COLOR3 >= 0) && (p.team == (TEAM_COLOR3 +1)) )
+ TEAM3 = TEAM3 + 1;
+ if( (TEAM_COLOR4 >= 0) && (p.team == (TEAM_COLOR4 +1)) )
+ TEAM4 = TEAM4 + 1;
+
+ p = find(p, classname, "player");
+ }
+
+ // Find the team with the least players.
+
+ newcolor = TEAM_COLOR1;
+ t = TEAM1;
+
+ if ( (TEAM_COLOR2 >= 0) && (TEAM2 < t) )
+ {
+ newcolor = TEAM_COLOR2;
+ t = TEAM2;
+ }
+
+ if ( (TEAM_COLOR3 >= 0) && (TEAM3 < t) )
+ {
+ newcolor = TEAM_COLOR3;
+ t = TEAM3;
+ }
+
+ if ( (TEAM_COLOR4 >= 0) && (TEAM4 < t) )
+ {
+ newcolor = TEAM_COLOR4;
+ t = TEAM4;
+ }
+
+ // Put the player on a the new team.
+
+ n = ftos(newcolor);
+ stuffcmd(self, "color ");
+ stuffcmd(self, n);
+ stuffcmd(self, "\n");
+
+ sprint(self, "You have been assigned color ");
+ sprint(self, n);
+ sprint(self, "\nLegal colors are:");
+ if(TEAM_COLOR1 >= 0)
+ {
+ n = ftos(TEAM_COLOR1);
+ sprint(self, " ");
+ sprint(self, n);
+ }
+ if(TEAM_COLOR2 >= 0)
+ {
+ n = ftos(TEAM_COLOR2);
+ sprint(self, " ");
+ sprint(self, n);
+ }
+ if(TEAM_COLOR3 >= 0)
+ {
+ n = ftos(TEAM_COLOR3);
+ sprint(self, " ");
+ sprint(self, n);
+ }
+ if(TEAM_COLOR4 >= 0)
+ {
+ n = ftos(TEAM_COLOR4);
+ sprint(self, " ");
+ sprint(self, n);
+ }
+
+ sprint(self, "\n");
+
+ self.lastteam = newcolor + 1; // Remember what team we're on
+ self.team = newcolor + 1;
+ return FALSE;
+};
+
+/*
+===============
+TeamCheckLock
+
+Check for team changing and perform whatever actions are neccessary.
+===============
+*/
+void() TeamCheckLock =
+{
+ local float n;
+ local string s;
+
+ // Don't do anything if teamplay is negative
+ if ( teamplay < 0 )
+ return;
+
+ if (self.lastteam >= 128) {
+ self.lastteam = self.lastteam - 128;
+ stuffcmd(self, "color ");
+ n = self.lastteam - 1;
+ s = ftos(n);
+ stuffcmd(self, s);
+ stuffcmd(self, "\n");
+ return;
+ }
+
+ if ( !TeamColorIsLegal(self.team - 1) && (self.team == self.lastteam) )
+ self.lastteam = -1;
+
+ // Check to see if the player has changed colors
+ if (self.team != self.lastteam)
+ {
+
+ // Player has changed colors
+
+ // If teams are static and we've been on some team already,
+ // put us back on the team we were on.
+
+ if ( (teamplay & TEAM_STATIC_TEAMS) && (self.lastteam >= 0) )
+ {
+ if ( TeamColorIsLegal(self.lastteam - 1) )
+ {
+ sprint(self, "You cannot change teams.\n");
+ stuffcmd(self, "color ");
+ n = self.lastteam - 1;
+ s = ftos(n);
+ stuffcmd(self, s);
+ stuffcmd(self, "\n");
+ return;
+ }
+ else
+ self.lastteam = -50;
+ // If we're on an illegal team, force a change.
+ }
+
+ // If teamlock is turned off, don't do anything more.
+ if ( !(teamplay & TEAM_LOCK_COLORS) )
+ {
+ if ( teamplay & TEAM_STATIC_TEAMS )
+ self.lastteam = self.team;
+ return;
+ }
+
+ if(self.lastteam > 0) {
+ s = ftos(self.lastteam);
+ // case base respawn
+ if (self.killed != 1)
+ self.killed = 2;
+ T_Damage(self,self,self,1000); // Kill the player
+ }
+ self.frags = 0; // Zero out frags
+ if(TeamCheckTeam())
+ self.lastteam = self.team;
+ }
+};
+
+/*
+=======================
+TossBackPack
+
+Original idea by Vhold
+Rewritten by John Spickes
+
+Toss out a backpack containing some ammo from your current weapon,
+and any weapons you don't have.
+=======================
+*/
+void() TossBackpack =
+{
+ local entity item;
+
+ // If we don't have any ammo, return
+ if(self.currentammo <= 0)
+ return;
+
+ item = spawn();
+
+ // See if you have the Shotgun or Super Shotgun on
+ if ( (self.weapon == IT_SHOTGUN) || (self.weapon == IT_SUPER_SHOTGUN) )
+ {
+ if( self.ammo_shells >= 20 ) {
+ item.ammo_shells = 20;
+ self.ammo_shells = self.ammo_shells - 20;
+ }
+ else
+ {
+ item.ammo_shells = self.ammo_shells;
+ self.ammo_shells = 0;
+ }
+ }
+
+ // See if you have neither the Shotgun or Super Shotgun
+ if ( !(self.items & IT_SHOTGUN) && !(self.items & IT_SUPER_SHOTGUN) )
+ {
+ if( self.ammo_shells >= 20 ) {
+ item.ammo_shells = 20;
+ self.ammo_shells = self.ammo_shells - 20;
+ }
+ else
+ {
+ item.ammo_shells = self.ammo_shells;
+ self.ammo_shells = 0;
+ }
+ }
+
+ // See if we are using a nailgun
+ if ( (self.weapon == IT_NAILGUN) || (self.weapon == IT_SUPER_NAILGUN) )
+ {
+ if( self.ammo_nails >= 20 )
+ {
+ item.ammo_nails = 20;
+ self.ammo_nails = self.ammo_nails - 20;
+ }
+ else
+ {
+ item.ammo_nails = self.ammo_nails;
+ self.ammo_nails = 0;
+ }
+ }
+ // Check to see if we have neither nailgun
+ if ( !(self.items & IT_NAILGUN) && !(self.items & IT_SUPER_NAILGUN) )
+ {
+ if( self.ammo_nails >= 20 )
+ {
+ item.ammo_nails = 20;
+ self.ammo_nails = self.ammo_nails - 20;
+ }
+ else
+ {
+ item.ammo_nails = self.ammo_nails;
+ self.ammo_nails = 0;
+ }
+ }
+
+ // See if we are using a grenade or rocket launcher
+ if ( (self.weapon == IT_GRENADE_LAUNCHER) || (self.weapon == IT_ROCKET_LAUNCHER) )
+ {
+ if( self.ammo_rockets >= 10 )
+ {
+ item.ammo_rockets = 10;
+ self.ammo_rockets = self.ammo_rockets - 10;
+ }
+ else
+ {
+ item.ammo_rockets = self.ammo_rockets;
+ self.ammo_rockets = 0;
+ }
+ }
+ // See if we have neither the Grenade or rocket launcher
+ if ( !(self.items & IT_GRENADE_LAUNCHER) && !(self.items & IT_ROCKET_LAUNCHER) )
+ {
+ if( self.ammo_rockets >= 10 )
+ {
+ item.ammo_rockets = 10;
+ self.ammo_rockets = self.ammo_rockets - 10;
+ }
+ else
+ {
+ item.ammo_rockets = self.ammo_rockets;
+ self.ammo_rockets = 0;
+ }
+ }
+
+ // See if we're using the lightning gun
+ if ( self.weapon == IT_LIGHTNING )
+ {
+ if( self.ammo_cells >= 20 )
+ {
+ item.ammo_cells = 20;
+ self.ammo_cells = self.ammo_cells - 20;
+ }
+ else
+ {
+ item.ammo_cells = self.ammo_cells;
+ self.ammo_cells = 0;
+ }
+ }
+ // see if we don't have the lightning gun
+ if ( !(self.items & IT_LIGHTNING) )
+ {
+ if( self.ammo_cells >= 20 )
+ {
+ item.ammo_cells = 20;
+ self.ammo_cells = self.ammo_cells - 20;
+ }
+ else
+ {
+ item.ammo_cells = self.ammo_cells;
+ self.ammo_cells = 0;
+ }
+ }
+
+ item.owner = self;
+ makevectors(self.v_angle);
+
+ setorigin(item, self.origin + '0 0 16');
+ item.velocity = aim(self, 1000);
+ item.velocity = item.velocity * 500;
+ item.flags = FL_ITEM;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_BOUNCE;
+
+ setmodel (item, "progs/backpack.mdl");
+ setsize(item, '-16 -16 0', '16 16 56');
+ item.touch = BackpackTouch;
+ item.nextthink = time + 120; // remove after 2 minutes
+ item.think = SUB_Remove;
+
+ W_SetCurrentAmmo();
+
+};
+
+void() Team_weapon_touch =
+{
+ local float hadammo, best, new, old;
+ local entity stemp;
+
+ if (!(other.flags & FL_CLIENT))
+ return;
+ // Don't let the owner pick up his own weapon for a second.
+ if ( (other == self.owner) && ( (self.nextthink - time) > 119 ) )
+ return;
+
+// if the player was using his best weapon, change up to the new one if better
+ stemp = self;
+ self = other;
+ best = W_BestWeapon();
+ self = stemp;
+
+ if (self.classname == "weapon_nailgun")
+ {
+ hadammo = other.ammo_nails;
+ new = IT_NAILGUN;
+ }
+ else if (self.classname == "weapon_supernailgun")
+ {
+ hadammo = other.ammo_rockets;
+ new = IT_SUPER_NAILGUN;
+ }
+ else if (self.classname == "weapon_supershotgun")
+ {
+ hadammo = other.ammo_rockets;
+ new = IT_SUPER_SHOTGUN;
+ }
+ else if (self.classname == "weapon_rocketlauncher")
+ {
+ hadammo = other.ammo_rockets;
+ new = IT_ROCKET_LAUNCHER;
+ }
+ else if (self.classname == "weapon_grenadelauncher")
+ {
+ hadammo = other.ammo_rockets;
+ new = IT_GRENADE_LAUNCHER;
+ }
+ else if (self.classname == "weapon_lightning")
+ {
+ hadammo = other.ammo_rockets;
+ new = IT_LIGHTNING;
+ }
+ else
+ objerror ("Team_weapon_touch: unknown classname");
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other, "\n");
+// weapon touch sound
+ sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+ bound_other_ammo ();
+
+// change to the weapon
+ old = other.items;
+ other.items = other.items | new;
+
+ remove(self);
+ self = other;
+
+ if (!deathmatch)
+ self.weapon = new;
+ else
+ Deathmatch_Weapon (old, new);
+
+ W_SetCurrentAmmo();
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+void() TossWeapon =
+{
+ local entity item;
+
+ if((self.weapon == IT_AXE) || (self.weapon == IT_SHOTGUN) ||
+ (self.weapon == IT_HOOK))
+ return;
+
+ item = spawn();
+ item.owner = self;
+ makevectors(self.v_angle);
+
+ setorigin(item, self.origin + '0 0 16');
+ item.velocity = aim(self, 1000);
+ item.velocity = item.velocity * 500;
+ item.flags = FL_ITEM;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_BOUNCE;
+
+ if(self.weapon == IT_SUPER_SHOTGUN)
+ {
+ setmodel (item, "progs/g_shot.mdl");
+ item.weapon = IT_SUPER_SHOTGUN;
+ item.netname = "Double-barrelled Shotgun";
+ item.classname = "weapon_supershotgun";
+ self.items = self.items - IT_SUPER_SHOTGUN;
+ }
+
+ if( self.weapon == IT_NAILGUN )
+ {
+ setmodel (item, "progs/g_nail.mdl");
+ item.weapon = IT_NAILGUN;
+ item.netname = "nailgun";
+ item.classname = "weapon_nailgun";
+ self.items = self.items - IT_NAILGUN;
+ }
+
+ if( self.weapon == IT_SUPER_NAILGUN )
+ {
+ setmodel (item, "progs/g_nail2.mdl");
+ item.weapon = IT_SUPER_NAILGUN;
+ item.netname = "Super Nailgun";
+ item.classname = "weapon_supernailgun";
+ self.items = self.items - IT_SUPER_NAILGUN;
+ }
+
+ if( self.weapon == IT_GRENADE_LAUNCHER || self.weapon == IT_FLAMETHROWER)
+ {
+ setmodel (item, "progs/g_rock.mdl");
+ item.weapon = 3;
+ item.netname = "Grenade Launcher";
+ item.classname = "weapon_grenadelauncher";
+ self.items = self.items - IT_GRENADE_LAUNCHER;
+ }
+
+ if( self.weapon == IT_ROCKET_LAUNCHER )
+ {
+ setmodel (item, "progs/g_rock2.mdl");
+ item.weapon = 3;
+ item.netname = "Rocket Launcher";
+ item.classname = "weapon_rocketlauncher";
+ self.items = self.items - IT_ROCKET_LAUNCHER;
+ }
+
+ if( self.weapon == IT_LIGHTNING )
+ {
+ setmodel (item, "progs/g_light.mdl");
+ item.weapon = 3;
+ item.netname = "Thunderbolt";
+ item.classname = "weapon_lightning";
+ self.items = self.items - IT_LIGHTNING;
+ }
+ setsize(item, '-16 -16 0', '16 16 56');
+ item.touch = Team_weapon_touch;
+ item.think = SUB_Remove;
+ item.nextthink = time + 120;
+
+ self.weapon = W_BestWeapon();
+ W_SetCurrentAmmo();
+};
+
+void() SilentKill;
+void() SUB_regen;
+
+void() TeamCaptureRegenFlags =
+{
+ local entity f;
+
+ self = find(world, classname, "item_flag_team1");
+ if (self != world)
+ SUB_regen();
+ self = find(world, classname, "item_flag_team2");
+ if (self != world)
+ SUB_regen();
+};
+
+void() TeamCaptureFlagSanityCheck =
+{
+ local entity p;
+
+ // Ok, a flag must be in one of three states
+ // 1. At home base (though we shouldn't be called in that case)
+ // 2. On enemy player
+ // 3. A copy is sitting around somewhere, waiting to be picked up
+
+ // at home base?
+ if (self.model != string_null) {
+ self.think = TeamCaptureFlagSanityCheck;
+ self.nextthink = time + 30;
+ return; // its at home, no prob
+ }
+
+ // on enemy player?
+ p = find(world, classname, "player");
+ while (p != world) {
+ if ((p.team != self.team) && (p.player_flag & ITEM_ENEMY_FLAG)) {
+ self.think = TeamCaptureFlagSanityCheck;
+ self.nextthink = time + 30;
+ return; // enemy player has it
+ }
+ p = find(p, classname, "player");
+ }
+
+ // copy sitting around somewhere
+ p = find(world, classname, "info_dropped_flag");
+ while (p != world) {
+ if (p.team == self.team) {
+ self.think = TeamCaptureFlagSanityCheck;
+ self.nextthink = time + 30;
+ return; // its out hanging around
+ }
+ p = find(p, classname, "info_dropped_flag");
+ }
+ // didn't find it, oh my
+ // regen this one
+ SUB_regen();
+};
+
+void() TeamCaptureFlagTouch =
+{
+ local entity p, oself;
+
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+
+ if (other.team != other.lastteam)
+ return; // something is fishy, somebody is playing with colors
+
+ if (self.team == other.team) {
+ // same team, if the flag is *not* at the base, return
+ // it to base. we overload the 'cnt' field for this
+ if (self.cnt) {
+ // the flag is at home base. if the player has the enemy
+ // flag, he's just won!
+
+ if (other.player_flag & ITEM_ENEMY_FLAG) {
+ bprint(other.netname);
+ if (other.team == TEAM_COLOR1 + 1)
+ bprint(" πß≡⌠⌡≥σΣ the ┬╠╒┼ flag!\n"); // blue
+ else
+ bprint(" πß≡⌠⌡≥σΣ the ╥┼─ flag!\n"); // red
+ other.items = other.items - (other.items & (IT_KEY1 | IT_KEY2));
+
+ sound (other, CHAN_VOICE, "doors/meduse.wav", 1, ATTN_NONE);
+ // other gets another 10 frag bonus
+ other.frags = other.frags + TEAM_CAPTURE_CAPTURE_BONUS;
+
+ // Ok, let's do the player loop, hand out the bonuses
+ p = find(world, classname, "player");
+ while (p != world) {
+ self = p;
+ self.killed = 0;
+ if (self.team == other.team && self != other)
+ self.frags = self.frags + TEAM_CAPTURE_TEAM_BONUS;
+ if (self.team != other.team)
+ centerprint(self, "Your flag was captured!\n");
+ else if (self.team == other.team)
+ centerprint(self, "Your team captured the flag!\n");
+ self.player_flag = self.player_flag - (self.player_flag & ITEM_ENEMY_FLAG);
+// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
+// client.qc:CheckDimLight
+// self.effects = self.effects - (self.effects & EF_DIMLIGHT);
+
+ p = find(p, classname, "player");
+ }
+ // respawn flags
+ TeamCaptureRegenFlags();
+ return;
+ }
+ return; // its at home base already
+ }
+ // hey, its not home. return it by teleporting it back
+ bprint(other.netname);
+ if (other.team == TEAM_COLOR1 + 1)
+ bprint(" ≥σ⌠⌡≥εσΣ the ╥┼─ flag!\n"); // red
+ else
+ bprint(" ≥σ⌠⌡≥εσΣ the ┬╠╒┼ flag!\n"); // blue
+ other.frags = other.frags + TEAM_CAPTURE_RECOVERY_BONUS;
+ sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ remove(self); // oops it gone
+ p = find(world, classname, "player");
+ while (p != world) {
+ if (p.team != other.team)
+ centerprint(p, "Enemy flag has been returned to base!\n");
+ else if (p.team == other.team)
+ centerprint(p, "Your flag has been returned to base!\n");
+ p = find(p, classname, "player");
+ }
+ if (other.team == TEAM_COLOR1 + 1) {
+ self = find(world, classname, "item_flag_team1");
+ if (self != world) {
+ self.think = SUB_Null; // its at home, no need to think
+ SUB_regen();
+ }
+ } else { // TEAM_COLOR2
+ self = find(world, classname, "item_flag_team2");
+ if (self != world) {
+ self.think = SUB_Null; // its at home, no need to think
+ SUB_regen();
+ }
+ }
+ return;
+ }
+
+ // hey, its not our flag, pick it up
+ bprint(other.netname);
+ if (other.team == TEAM_COLOR1 + 1)
+ bprint(" τ∩⌠ the ┬╠╒┼ flag!\n"); // blue
+ else
+ bprint(" τ∩⌠ the ╥┼─ flag!\n"); // red
+ if (TEAM_CAPTURE_FLAG_BONUS)
+ other.frags = other.frags + TEAM_CAPTURE_FLAG_BONUS;
+// centerprint(other, "YOU GOT THE ENEMY FLAG!\n\nRETURN TO BASE!\n");
+ centerprint(other, "┘╧╒ ╟╧╘ ╘╚┼ ┼╬┼═┘ ╞╠┴╟\n\n╥┼╘╒╥╬ ╘╧ ┬┴╙┼\n");
+ sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+
+ other.player_flag = other.player_flag + ITEM_ENEMY_FLAG;
+ other.items = other.items | self.items;
+ // turn on the glow
+// ZOID, next line isn't needed, EF_DIMLIGHT is handled by
+// client.qc:CheckDimLight
+// other.effects = other.effects | EF_DIMLIGHT;
+
+ // make the flag here disappear
+ if (self.cnt) {
+ // home base flags stay
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ // set up sanity check
+ self.think = TeamCaptureFlagSanityCheck;
+ self.nextthink = time + 30; // 30 seconds pre check
+ } else
+ remove(self); // dropped flags recyclce
+
+ p = find(world, classname, "player");
+ while (p != world) {
+ if (p != other) {
+ if (p.team != other.team)
+ centerprint(p, "Your flag has been taken!\n");
+ else if (p.team == other.team)
+ centerprint(p, "Your team has the enemy flag!\n");
+ }
+ p = find(p, classname, "player");
+ }
+};
+
+void() TeamCaptureReturnFlag =
+{
+ local entity f, p;
+
+ f = world;
+ if (self.team == TEAM_COLOR1 + 1) {
+ f = self;
+ self = find(world, classname, "item_flag_team1");
+ if (self != world) {
+ self.think = SUB_Null; // its at home, no need to think
+ SUB_regen();
+ }
+ } else { // TEAM_COLOR2
+ f = self;
+ self = find(world, classname, "item_flag_team2");
+ if (self != world) {
+ self.think = SUB_Null; // its at home, no need to think
+ SUB_regen();
+ }
+ }
+ if (f == world)
+ return;
+ p = find(world, classname, "player");
+ while (p != world) {
+ if (p.team != f.team)
+ centerprint(p, "Enemy flag has been returned to base!\n");
+ else if (p.team == f.team)
+ centerprint(p, "Your flag has been returned to base!\n");
+ p = find(p, classname, "player");
+ }
+ remove(f);
+};
+
+void() TeamCaptureDropFlag =
+{
+ local entity item, f;
+
+ if (!(self.player_flag & ITEM_ENEMY_FLAG))
+ return;
+
+ self.player_flag = self.player_flag - ITEM_ENEMY_FLAG;
+
+ bprint(self.netname);
+ if (self.lastteam == TEAM_COLOR1 + 1)
+ bprint(" ∞∩≤⌠ the ┬╠╒┼ flag!\n"); // blue
+ else
+ bprint(" ∞∩≤⌠ the ╥┼─ flag!\n"); // red
+
+ item = spawn();
+ item.items = self.items & (IT_KEY1 | IT_KEY2);
+ item.origin = self.origin - '0 0 24';
+ item.cnt = 0; // it's NOT at home base
+ //NOTE! We check lastteam here instead of team--this is because
+ //in the mode where we change colors, we get killed
+ if (self.lastteam == TEAM_COLOR1 + 1) {
+ item.classname = "info_dropped_flag";
+ item.team = TEAM_COLOR2 + 1;
+ f = find(world, classname, "item_flag_team2");
+ if (f != world) {
+ setmodel(item, f.mdl);
+ item.noise = f.noise;
+ } else {
+ setmodel(item, "progs/lavaball.mdl");
+ item.noise = "";
+ }
+ } else { // TEAM_COLOR2
+ item.classname = "info_dropped_flag";
+ item.team = TEAM_COLOR1 + 1;
+ f = find(world, classname, "item_flag_team1");
+ if (f != world) {
+ setmodel(item, f.mdl);
+ item.noise = f.noise;
+ } else {
+ setmodel(item, "progs/lavaball.mdl");
+ item.noise = "";
+ }
+ }
+ item.velocity_z = 300;
+ item.velocity_x = 0;
+ item.velocity_y = 0;
+ item.touch = TeamCaptureFlagTouch;
+ item.flags = FL_ITEM;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize(item, '-16 -16 -24', '16 16 32');
+ item.effects = item.effects | EF_DIMLIGHT; // make it glow
+ // return the flag to base if no one picks it up for a while
+ item.think = TeamCaptureReturnFlag;
+ item.nextthink = time + 30;
+};
+
+// self is player
+entity() TeamCaptureSpawn =
+{
+
+ if (!(teamplay & TEAM_CAPTURE_FLAG))
+ return world;
+
+ if (self.team == TEAM_COLOR1 + 1) {
+ team1_lastspawn = find(team1_lastspawn, classname, "info_player_team1");
+ if (team1_lastspawn == world)
+ team1_lastspawn = find(team1_lastspawn, classname, "info_player_team1");
+ return team1_lastspawn;
+ } else { // if (self.team == TEAM_COLOR2 + 1)
+ team2_lastspawn = find(team2_lastspawn, classname, "info_player_team2");
+ if (team2_lastspawn == world)
+ team2_lastspawn = find(team2_lastspawn, classname, "info_player_team2");
+ return team2_lastspawn;
+ }
+ return world;
+};
+
+// ZOID -- total up team scores and set everyone's frag count to the team
+// total
+void() TeamScores =
+{
+ local float team1, team2, team3, team4;
+ local entity p;
+
+ if (teamscored || !teamplay)
+ return; // already scored or not in team mode
+
+ teamscored = 1;
+
+ team1 = 0;
+ team2 = 0;
+ team3 = 0;
+ team4 = 0;
+
+dprint("TeamScores()\n");
+ p = find(world, classname, "player");
+ while (p != world) {
+dprint(" Player=");
+dprint(p.netname);
+dprint(" Team=");
+dprint(ftos(p.team));
+dprint(" Frags=");
+dprint(ftos(p.frags));
+dprint("\n");
+ if (p.team == TEAM_COLOR1 + 1)
+ team1 = team1 + p.frags;
+ else if (p.team == TEAM_COLOR2 + 1)
+ team2 = team2 + p.frags;
+ else if (p.team == TEAM_COLOR3 + 1)
+ team3 = team3 + p.frags;
+ else if (p.team == TEAM_COLOR4 + 1)
+ team4 = team4 + p.frags;
+ p = find(p, classname, "player");
+ }
+dprint(" Totals: team1=");
+dprint(ftos(team1));
+dprint(" team2=");
+dprint(ftos(team2));
+dprint("\n");
+ p = find(world, classname, "player");
+ while (p != world) {
+ if (p.team == TEAM_COLOR1 + 1)
+ p.frags = team1;
+ else if (p.team == TEAM_COLOR2 + 1)
+ p.frags = team2;
+ else if (p.team == TEAM_COLOR3 + 1)
+ p.frags = team3;
+ else if (p.team == TEAM_COLOR4 + 1)
+ p.frags = team4;
+ p = find(p, classname, "player");
+ }
+};
+
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/telefrag.qc src/telefrag.qc
--- v106qc/telefrag.qc Wed Dec 31 19:00:00 1969
+++ src/telefrag.qc Mon Oct 7 20:42:27 1996
@@ -0,0 +1,61 @@
+/*
+**
+** _telefrg.qc (Telefrag Code, 1.1)
+**
+** Copyright (C) 1996 Johannes Plass
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** Author: Johannes Plass (plass@dipmza.physik.uni-mainz.de)
+**
+** --
+** Sniped by Zoid for ThreeWave Mods, GPL respected
+**
+*/
+
+entity() SelectSpawnPoint;
+
+entity(entity spot) TelefragSelectSpawnPoint =
+{
+ local entity e, firstspot;
+ local float search_spot;
+
+ search_spot = 25;
+ firstspot = spot;
+
+ while (search_spot) {
+ e = findradius(spot.origin, 100);
+ if (!e)
+ search_spot = 0;
+ else {
+ local float occupied;
+ occupied = 0;
+ while (!occupied && !(!e)) {
+ if (e.classname == "player" && e.deadflag == DEAD_NO)
+ occupied = 1;
+ else
+ e = e.chain;
+ }
+ if (occupied) {
+ spot = SelectSpawnPoint();
+ search_spot = search_spot - 1;
+ if (spot == firstspot)
+ search_spot = 0;
+ } else
+ search_spot = 0;
+ }
+ }
+ return (spot);
+};
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/triggers.qc src/triggers.qc
--- v106qc/triggers.qc Thu Sep 26 11:15:40 1996
+++ src/triggers.qc Sun Oct 6 15:01:39 1996
@@ -381,7 +381,6 @@
// only teleport living creatures
if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
return;
-
SUB_UseTargets ();
// put a tfog where the player was
@@ -405,13 +404,14 @@
other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y);
return;
}
-
setorigin (other, t.origin);
other.angles = t.mangle;
+
if (other.classname == "player")
{
other.fixangle = 1; // turn this way immediately
other.teleport_time = time + 0.7;
+
if (other.flags & FL_ONGROUND)
other.flags = other.flags - FL_ONGROUND;
other.velocity = v_forward * 300;
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/weapons.qc src/weapons.qc
--- v106qc/weapons.qc Mon Sep 30 03:08:08 1996
+++ src/weapons.qc Wed Oct 9 21:37:50 1996
@@ -5,11 +5,16 @@
void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
void(vector org, vector vel, float damage) SpawnBlood;
void() SuperDamageSound;
+void() HasteSound;
+//Flamethrower
+void () W_FireFlame;
// called by worldspawn
void() W_Precache =
{
+ precache_sound ("hknight/hit.wav"); // flamethrower
+
precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
precache_sound ("weapons/rocket1i.wav"); // spike gun
precache_sound ("weapons/sgun1.wav");
@@ -22,6 +27,9 @@
precache_sound ("weapons/grenade.wav"); // grenade launcher
precache_sound ("weapons/bounce.wav"); // grenade bounce
precache_sound ("weapons/shotgn2.wav"); // super shotgun
+ precache_sound2 ("blob/land1.wav"); // chain go splorch!
+ precache_sound ("plats/medplat1.wav"); // chain cranking out
+ precache_sound ("doors/ddoor1.wav"); // chain cranking in
};
float() crandom =
@@ -767,6 +775,12 @@
self.weaponmodel = "progs/v_axe.mdl";
self.weaponframe = 0;
}
+ else if (self.weapon == IT_HOOK)
+ {
+ self.currentammo = 0;
+ self.weaponmodel = "progs/v_axe.mdl";
+ self.weaponframe = 0;
+ }
else if (self.weapon == IT_SHOTGUN)
{
self.currentammo = self.ammo_shells;
@@ -809,6 +823,13 @@
self.weaponframe = 0;
self.items = self.items | IT_ROCKETS;
}
+ else if (self.weapon == IT_FLAMETHROWER)
+ {
+ self.currentammo = self.ammo_shells;
+ self.weaponmodel = "progs/v_rock.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_SHELLS;
+ }
else if (self.weapon == IT_LIGHTNING)
{
self.currentammo = self.ammo_cells;
@@ -848,7 +869,7 @@
if (self.currentammo > 0)
return TRUE;
- if (self.weapon == IT_AXE)
+ if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
return TRUE;
self.weapon = W_BestWeapon ();
@@ -874,6 +895,8 @@
void() player_nail1;
void() player_light1;
void() player_rocket1;
+void() player_chain1;
+void() player_chain3;
void() W_Attack =
{
@@ -897,18 +920,33 @@
player_axec1 ();
else
player_axed1 ();
+ // RUNE: rune of hell magic
+ if (self.player_flag & ITEM_RUNE3_FLAG) {
+ self.attack_finished = time + 0.3;
+ HasteSound();
+ } else
self.attack_finished = time + 0.5;
}
else if (self.weapon == IT_SHOTGUN)
{
player_shot1 ();
W_FireShotgun ();
+ // RUNE: rune of hell magic
+ if (self.player_flag & ITEM_RUNE3_FLAG) {
+ self.attack_finished = time + 0.3;
+ HasteSound();
+ } else
self.attack_finished = time + 0.5;
}
else if (self.weapon == IT_SUPER_SHOTGUN)
{
player_shot1 ();
W_FireSuperShotgun ();
+ // RUNE: rune of hell magic
+ if (self.player_flag & ITEM_RUNE3_FLAG) {
+ self.attack_finished = time + 0.4;
+ HasteSound();
+ } else
self.attack_finished = time + 0.7;
}
else if (self.weapon == IT_NAILGUN)
@@ -923,20 +961,48 @@
{
player_rocket1();
W_FireGrenade();
+ // RUNE: rune of hell magic
+ if (self.player_flag & ITEM_RUNE3_FLAG) {
+ self.attack_finished = time + 0.3;
+ HasteSound();
+ } else
self.attack_finished = time + 0.6;
}
else if (self.weapon == IT_ROCKET_LAUNCHER)
{
player_rocket1();
W_FireRocket();
+ // RUNE: rune of hell magic
+ if (self.player_flag & ITEM_RUNE3_FLAG) {
+ self.attack_finished = time + 0.4;
+ HasteSound();
+ } else
self.attack_finished = time + 0.8;
}
+// Flamethrower
+ else if (self.weapon == IT_FLAMETHROWER)
+ {
+ player_shot1();
+ W_FireFlame();
+ if (self.waterlevel >2)
+ self.attack_finished = time + 1;
+ else
+ self.attack_finished = time + 0.1;
+ }
else if (self.weapon == IT_LIGHTNING)
{
player_light1();
self.attack_finished = time + 0.1;
sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
}
+ else if (self.weapon == IT_HOOK)
+ {
+ if (!self.hook_out)
+ player_chain1();
+ else
+ player_chain3();
+ self.attack_finished = time + 0.1;
+ }
};
/*
@@ -952,51 +1018,52 @@
it = self.items;
am = 0;
- if (self.impulse == 1)
- {
+ if (self.impulse == 1) {
+ if (self.weapon == IT_AXE)
+ fl = IT_HOOK;
+ else
fl = IT_AXE;
- }
- else if (self.impulse == 2)
- {
+ } else if (self.impulse == 2) {
fl = IT_SHOTGUN;
if (self.ammo_shells < 1)
am = 1;
- }
- else if (self.impulse == 3)
- {
+ } else if (self.impulse == 3) {
fl = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
am = 1;
- }
- else if (self.impulse == 4)
- {
+ } else if (self.impulse == 4) {
fl = IT_NAILGUN;
if (self.ammo_nails < 1)
am = 1;
- }
- else if (self.impulse == 5)
- {
+ } else if (self.impulse == 5) {
fl = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
am = 1;
- }
- else if (self.impulse == 6)
- {
+ } else if (self.impulse == 6) {
+ if (self.weapon != IT_GRENADE_LAUNCHER && self.ammo_rockets > 0) {
fl = IT_GRENADE_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
- }
- else if (self.impulse == 7)
- {
+ } else if (self.ammo_shells > 1) {
+ fl = IT_FLAMETHROWER;
+ if (self.ammo_shells < 1)
+ am = 1;
+ } else
+ am = 1;
+ } else if (self.impulse == 7) {
fl = IT_ROCKET_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
- }
- else if (self.impulse == 8)
- {
+ } else if (self.impulse == 8) {
fl = IT_LIGHTNING;
if (self.ammo_cells < 1)
am = 1;
+ } else if (self.impulse == 22) {
+ fl = IT_HOOK;
+ } else if (self.impulse == 50) {
+ fl = IT_FLAMETHROWER;
+ if (self.ammo_shells < 1)
+ am = 1;
}
self.impulse = 0;
@@ -1017,6 +1084,15 @@
// set weapon, set ammo
//
self.weapon = fl;
+ if (self.weapon == IT_FLAMETHROWER)
+ sprint (self,"Flamethrower selected.\n");
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ sprint (self,"Grenade Launcher selected.\n");
+ else if (self.weapon == IT_AXE)
+ sprint(self, "Axe selected.\n");
+ else if (self.weapon == IT_HOOK)
+ sprint(self, "Grappling hook selected.\n");
+
W_SetCurrentAmmo ();
};
@@ -1035,11 +1111,13 @@
self.ammo_shells = 100;
self.items = self.items |
IT_AXE |
+ IT_HOOK |
IT_SHOTGUN |
IT_SUPER_SHOTGUN |
IT_NAILGUN |
IT_SUPER_NAILGUN |
IT_GRENADE_LAUNCHER |
+ IT_FLAMETHROWER |
IT_ROCKET_LAUNCHER |
IT_KEY1 | IT_KEY2;
@@ -1069,48 +1147,37 @@
{
am = 0;
- if (self.weapon == IT_LIGHTNING)
- {
+ if (self.weapon == IT_LIGHTNING) {
self.weapon = IT_AXE;
- }
- else if (self.weapon == IT_AXE)
- {
+ } else if (self.weapon == IT_AXE) {
+ self.weapon = IT_HOOK;
+ } else if (self.weapon == IT_HOOK) {
self.weapon = IT_SHOTGUN;
if (self.ammo_shells < 1)
am = 1;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
+ } else if (self.weapon == IT_SHOTGUN) {
self.weapon = IT_SUPER_SHOTGUN;
if (self.ammo_shells < 2)
am = 1;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
+ } else if (self.weapon == IT_SUPER_SHOTGUN) {
self.weapon = IT_NAILGUN;
if (self.ammo_nails < 1)
am = 1;
- }
- else if (self.weapon == IT_NAILGUN)
- {
+ } else if (self.weapon == IT_NAILGUN) {
self.weapon = IT_SUPER_NAILGUN;
if (self.ammo_nails < 2)
am = 1;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
+ } else if (self.weapon == IT_SUPER_NAILGUN) {
self.weapon = IT_GRENADE_LAUNCHER;
if (self.ammo_rockets < 1)
am = 1;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.weapon = IT_ROCKET_LAUNCHER;
+ } else if (self.weapon == IT_GRENADE_LAUNCHER) {
+ self.weapon = IT_FLAMETHROWER;
if (self.ammo_rockets < 1)
am = 1;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
+ } else if (self.weapon == IT_FLAMETHROWER) {
+ self.weapon = IT_ROCKET_LAUNCHER;
+ } else if (self.weapon == IT_ROCKET_LAUNCHER) {
self.weapon = IT_LIGHTNING;
if (self.ammo_cells < 1)
am = 1;
@@ -1118,6 +1185,11 @@
if ( (it & self.weapon) && am == 0)
{
+ if (self.weapon == IT_FLAMETHROWER)
+ sprint(self,"Flamethrower\n");
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ sprint(self,"Grenade Launcher\n");
+
W_SetCurrentAmmo ();
return;
}
@@ -1181,6 +1253,10 @@
}
else if (self.weapon == IT_SHOTGUN)
{
+ self.weapon = IT_HOOK;
+ }
+ else if (self.weapon == IT_HOOK)
+ {
self.weapon = IT_AXE;
}
else if (self.weapon == IT_AXE)
@@ -1221,27 +1297,100 @@
dprint ("quad cheat\n");
};
+void() PrintLocation =
+{
+ local string p;
+
+ p = vtos(self.origin);
+
+ sprint(self, "You are at ");
+ sprint(self, p);
+ sprint(self, "\n");
+};
+
/*
============
ImpulseCommands
============
*/
+//ZOID: Note, changed it all to an if/else construct. No need to check
+//remaining impulses if we have one already. Much cleaner and a tad
+//more efficient. Using a non-existant impulse is still the worst case. :(
void() ImpulseCommands =
{
- if (self.impulse >= 1 && self.impulse <= 8)
+ if ((self.impulse >= 1 && self.impulse <= 8) || self.impulse == 22 ||
+ self.impulse == 50)
W_ChangeWeapon ();
- if (self.impulse == 9)
+ else if (self.impulse == 9)
CheatCommand ();
- if (self.impulse == 10)
+
+ else if (self.impulse == 10)
CycleWeaponCommand ();
- if (self.impulse == 11)
+
+ else if (self.impulse == 11)
ServerflagsCommand ();
- if (self.impulse == 12)
+
+ else if (self.impulse == 12)
CycleWeaponReverseCommand ();
- if (self.impulse == 255)
+ else if (self.impulse == 99)
+ PrintLocation();
+
+// *TEAMPLAY*
+// If we're allowed to drop items, enable impulse 20 and 21
+ else if ((teamplay & TEAM_DROP_ITEMS) && self.impulse == 20)
+ TossBackpack ();
+
+ else if ((teamplay & TEAM_DROP_ITEMS) && self.impulse == 21)
+ TossWeapon ();
+
+// *TEAMPLAY*
+// Impulse 25 prints info about the current teamplay settings.
+ else if (self.impulse == 25)
+ TeamPrintSettings ();
+
+// ** M U L T I S K I N 1.1 (start)
+
+// modified to not work in teamplay by Zoid, since you can't tell what color
+// people are
+ else if ((teamplay == 0) && ((self.impulse == 200) || (self.impulse == 201))) {
+ if (self.impulse == 200) {
+ self.skin = self.skin + 1;
+ if (self.skin == 19)
+ self.skin = 0;
+ } else if (self.impulse == 201) {
+ self.skin = self.skin - 1;
+ if (self.skin == -1)
+ self.skin = 18;
+ }
+ self.player_flag = self.player_flag - (self.player_flag & 65280);
+ self.player_flag = self.player_flag | (self.skin * 256);
+ if (self.skin == 0) centerprint(self, "SKIN: Quake himself (1)"); else
+ if (self.skin == 1) centerprint(self, "SKIN: Duke Nukem 3d (2)"); else
+ if (self.skin == 2) centerprint(self, "SKIN: Mr. Toad (3)"); else
+ if (self.skin == 3) centerprint(self, "SKIN: the Stormtrooper (4)"); else
+ if (self.skin == 4) centerprint(self, "SKIN: Max (5)"); else
+ if (self.skin == 5) centerprint(self, "SKIN: the Terminator (6)"); else
+ if (self.skin == 6) centerprint(self, "SKIN: Judge Dredd (7)"); else
+ if (self.skin == 7) centerprint(self, "SKIN: Camouflaged soldier (8)"); else
+ if (self.skin == 8) centerprint(self, "SKIN: Captain Picard (9)"); else
+ if (self.skin == 9) centerprint(self, "SKIN: the Wizzard (10)"); else
+ if (self.skin == 10) centerprint(self,"SKIN: the Predator (11)"); else
+ if (self.skin == 11) centerprint(self,"SKIN: Skeleton (12)"); else
+ if (self.skin == 12) centerprint(self,"SKIN: Wan-Fu (13)"); else
+ if (self.skin == 13) centerprint(self,"SKIN: Henry Rollins (14)"); else
+ if (self.skin == 14) centerprint(self,"SKIN: He-Man (15)"); else
+ if (self.skin == 15) centerprint(self,"SKIN: Boba (16)"); else
+ if (self.skin == 16) centerprint(self,"SKIN: Superman (17)"); else
+ if (self.skin == 17) centerprint(self,"SKIN: NYPD Cop (18)"); else
+ if (self.skin == 18) centerprint(self,"SKIN: Red/Yellow women dude (19)");
+ }
+
+// ** M U L T I S K I N 1.1 (end)
+
+ else if (self.impulse == 255)
QuadCheat ();
self.impulse = 0;
@@ -1259,6 +1408,11 @@
if (time < self.attack_finished)
return;
+//ZOID: Only call ImpulseCommands() if needed! This saves a good chunk
+//of cpu. 'profile' in console listed ImpulseCommands() as #1 user of
+//cpu (instructions), adding this one line caused it to not even be in
+//the top ten.
+ if (self.impulse)
ImpulseCommands ();
// check for attack
@@ -1278,10 +1432,9 @@
*/
void() SuperDamageSound =
{
- if (self.super_damage_finished > time)
- {
- if (self.super_sound < time)
- {
+// RUNE play super damage sound if player has Black Magic, too
+ if (self.super_damage_finished > time || (self.player_flag & ITEM_RUNE2_FLAG)) {
+ if (self.super_sound < time) {
self.super_sound = time + 1;
sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
}
@@ -1289,4 +1442,41 @@
return;
};
+/*
+========
+RegenerationSound
+
+Plays sound if needed
+========
+*/
+void() RegenerationSound =
+{
+// RUNE play healing sound if player has Elder Magic
+ if (self.player_flag & ITEM_RUNE4_FLAG) {
+ if (self.regeneration_sound < time) {
+ self.regeneration_sound = time + 1;
+ sound(self, CHAN_BODY, "items/r_item1.wav", 1, ATTN_NORM);
+ }
+ }
+ return;
+};
+
+/*
+========
+HasteSound
+
+Plays sound if needed
+========
+*/
+void() HasteSound =
+{
+// RUNE play haste (Chthon's roar) sound if player has Hell Magic
+ if (self.player_flag & ITEM_RUNE3_FLAG) {
+ if (self.haste_sound < time) {
+ self.haste_sound = time + 2;
+ sound(self, CHAN_BODY, "boss1/sight1.wav", 1, ATTN_NORM);
+ }
+ }
+ return;
+};
diff -u --new-file --ignore-all-space --exclude=*.dat v106qc/world.qc src/world.qc
--- v106qc/world.qc Thu Sep 26 11:15:40 1996
+++ src/world.qc Sat Oct 12 20:44:33 1996
@@ -172,6 +172,10 @@
void() worldspawn =
{
lastspawn = world;
+ runespawn = world;
+ runespawned = 0;
+ capturespawned = 0;
+ teamscored = 0;
InitBodyQue ();
// custom map attributes
@@ -241,6 +245,7 @@
precache_sound ("weapons/ax1.wav"); // ax swoosh
precache_sound ("player/axhit1.wav"); // ax hit meat
precache_sound ("player/axhit2.wav"); // ax hit world
+ precache_sound ("hknight/hit.wav"); // ZOID: hook launch
precache_sound ("player/h2ojump.wav"); // player jumping into water
precache_sound ("player/slimbrn2.wav"); // player enter slime
@@ -282,12 +287,23 @@
precache_model ("progs/spike.mdl");
precache_model ("progs/s_spike.mdl");
+// for hook
+ precache_model ("progs/v_spike.mdl");
+
precache_model ("progs/backpack.mdl");
precache_model ("progs/zom_gib.mdl");
precache_model ("progs/v_light.mdl");
+// rune precache
+ precache_model ("progs/end1.mdl");
+ precache_model ("progs/end2.mdl");
+ precache_model ("progs/end3.mdl");
+ precache_model ("progs/end4.mdl");
+ precache_sound ("items/protect3.wav");
+ precache_sound ("items/r_item1.wav");
+ precache_sound ("boss1/sight1.wav");
//
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
@@ -377,6 +393,7 @@
// respawned elsewhere
void(entity ent) CopyToBodyQue =
{
+ bodyque_head.skin = ent.skin;
bodyque_head.angles = ent.angles;
bodyque_head.model = ent.model;
bodyque_head.modelindex = ent.modelindex;